对于下面的
df
,你如何创建下面想要的输出?我特别关注元组列表的列表。
import pandas as pd
df = pd.DataFrame({'x':['ab_c_1.0.0','ab_c_1.0.1','ab_c_1.0.2','ab_c_1.1.0','ab_c_1.1.1','ab_c_1.2.0','ab_c_1.3.0','ab_c_1.3.1'],
'y':['a','b','c','d','e','f','g','h'],
'z':['i','j','k','l','m','n','o','p']})
df
>>>
x y z
0 ab_c_1.0.0 a i
1 ab_c_1.0.1 b j
2 ab_c_1.0.2 c k
3 ab_c_1.1.0 d l
4 ab_c_1.1.1 e m
5 ab_c_1.2.0 f n
6 ab_c_1.3.0 g o
7 ab_c_1.3.1 h p
期望的输出:
[[('a', 'i'), ('b', 'j'), ('c', 'k')],
[('d', 'l'), ('e', 'm')],
[('f', 'n')],
[('g', 'o'), ('h', 'p')]]
到目前为止,我一直认为我可以结合这样的东西来获得,可以这么说,钥匙:
for a in df['x']:
if a.endswith('.0'):
这个:
df.values.tolist()
然而,通过多个对象迭代多次显然是低效的。主要问题是除了检查
df
列中字符串的最后一位是否是x
之外,我不能用任何常量来分割0
,所以我不能使用滚动窗口或类似的东西.任何建议将不胜感激。
groupby
:
out = [list(zip(g['y'], g['z'])) for k, g in
df.groupby(df['x'].str.endswith('0').cumsum())]
将
x
的前导部分视为石斑鱼的变体,不包括最后一位数字:
out = [list(zip(g['y'], g['z'])) for k, g in
df.groupby(df['x'].str.extract(r'(.*).\d', expand=False))]
输出:
[[('a', 'i'), ('b', 'j'), ('c', 'k')],
[('d', 'l'), ('e', 'm')],
[('f', 'n')],
[('g', 'o'), ('h', 'p')]]
这里有一个方法:
res = ( df
.assign(x=df.x.str.extract(r'[^.]*\.([^.]*)')).set_index('x')
.apply(tuple, axis=1).groupby('x').agg(list).tolist() )
输出:
[[('a', 'i'), ('b', 'j'), ('c', 'k')], [('d', 'l'), ('e', 'm')], [('f', 'n')], [('g', 'o'), ('h', 'p')]]
请注意,传递给 extract() 的模式参数只是一个示例,可以对其进行调整以获得列
x
的任何组件对于其元组应在结果中组合在一起的所有行都是通用的。 (我使用的模式提取 x
列中以点分隔的字符串值中的第二个子字符串。)
我会首先在零开始的 x 列上找到索引。
left = 0
right = 1
slices = []
column_x = df['x']
while right < len(df):
if column_x[right][-1] == '0':
slices.append((left, right))
left = right
right += 1
slices.append((left, right))
我的切片数组显示了这些索引
[(0, 3), (3, 5), (5, 6), (6, 8)]
然后我将循环遍历所有切片,然后循环遍历切片的范围。
outer_list = []
for slice in slices:
inner_list = []
for index in range(slice[0], slice[1]):
inner_list.append((df.iloc[index, 1], df.iloc[index, 2]))
outer_list.append(inner_list)
print(outer_list)
[[('a', 'i'), ('b', 'j'), ('c', 'k')],
[('d', 'l'), ('e', 'm')],
[('f', 'n')],
[('g', 'o'), ('h', 'p')]]
你会在 outer_list 列表中得到想要的结果