鉴于此数据框:
import numpy as np
import pandas as pd
df = pd.DataFrame([['a1' , '1'], ['a2' , '2'], ['stop' , '3'], ['a2' , '4'], ['a4' , '5'], ['a5' , '6'], ['stop' , '7'], ['a6' , '8']],
columns=['a' , 'b'])
mask = df['a'].eq('stop')
print(df)
a b
0 a1 1
1 a2 2
2 stop 3
3 a2 4
4 a4 5
5 a5 6
6 stop 7
7 a6 8
处理将数据框转换为:
stop = mask[::-1].idxmax()
mask = mask[:stop]
c = df['a'][:stop].copy()
c.groupby(mask.cumsum()).apply(lambda s: s[s!='stop'].tolist())
a
0 [a1, a2]
1 [a2, a4, a5]
Name: a, dtype: object
何时停止'遇到会创建一个包含先前值的新数组。
我试图创建一个元组列表,其中列b从上面的数据帧df映射到列a的id。这是创建时的预期数据框结构:
0 [(a1 , 1), (a2 , 2)]
1 [(a2 , 3), (a4 , 4), (a5 , 5)]
到目前为止,这是我的尝试:
def get_value(x) :
to_ret = []
for a in x :
to_ret.append( (a , df[df['a'] == a]['b']))
return to_ret
c1 = c.groupby(mask.cumsum()).apply(lambda s: s[s!='stop'].tolist())
c1.map(lambda x : get_value(x))
呈现:
a
0 [(a1, [1]), (a2, [2, 4])]
1 [(a2, [2, 4]), (a4, [5]), (a5, [6])]
Name: a, dtype: object
这似乎是一个简单问题的复杂部分解决方案。是否有另一种转换此数据帧的方法?
答案 0 :(得分:3)
您好像可以将数据框转换为2元组系列,将 转换为类似的内容(groupby
+ apply
+ tolist
) -
df.apply(tuple, 1)[:stop]\
.groupby(mask.cumsum())\
.apply(lambda s: s[s.str[0] !='stop'].tolist())
a
0 [(a1, 1), (a2, 2)]
1 [(a2, 4), (a4, 5), (a5, 6)]
答案 1 :(得分:3)
另一个appraoch
df['stop_loc'] = (df['a'] == 'stop').cumsum()
df_new = df[(df['a'] != 'stop') & (df['stop_loc'] != df['stop_loc'].max())].groupby('stop_loc').apply(lambda x: list(zip(x.a, x.b)))
0 [(a1, 1), (a2, 2)]
1 [(a2, 4), (a4, 5), (a5, 6)]