在Python中折叠列中的某些行
我在熊猫中有这样一个数据帧:在Python中折叠列中的某些行,python,pandas,Python,Pandas,我在熊猫中有这样一个数据帧: ID rating G1 G2 G3 G4 G5 G6 G7 0 1 2.5 18 0 0 0 0 0 0 1 4 4.0 18 0 0 0 0 0 0 2 7 3.0 78 1 0
ID rating G1 G2 G3 G4 G5 G6 G7
0 1 2.5 18 0 0 0 0 0 0
1 4 4.0 18 0 0 0 0 0 0
2 7 3.0 78 1 0 0 0 0 0
3 1 4.0 21 7 8 10 30 40 20
4 21 3.0 18 0 0 0 0 0 0
5 7 2.0 18 80 10 11 8 0 0
6 41 3.5 18 0 9 10 0 0 0
ID H1 H2
0 1 [2.5,18] [4.0,21,7,8,10,30,40,20]
1 4 [4.0,18] Nan
2 7 [3.0,78] [2.0, 18, 80, 10, 11,8]
3 21 [3.0,18] Nan
4 41 [3.5,18,76,9,10] Nan
我希望通过ID对所有元素进行gruoping,从而在pandas中获得一种continuos数据帧,行数组条目如下:
ID rating G1 G2 G3 G4 G5 G6 G7
0 1 2.5 18 0 0 0 0 0 0
1 4 4.0 18 0 0 0 0 0 0
2 7 3.0 78 1 0 0 0 0 0
3 1 4.0 21 7 8 10 30 40 20
4 21 3.0 18 0 0 0 0 0 0
5 7 2.0 18 80 10 11 8 0 0
6 41 3.5 18 0 9 10 0 0 0
ID H1 H2
0 1 [2.5,18] [4.0,21,7,8,10,30,40,20]
1 4 [4.0,18] Nan
2 7 [3.0,78] [2.0, 18, 80, 10, 11,8]
3 21 [3.0,18] Nan
4 41 [3.5,18,76,9,10] Nan
你知道这是否可能吗?
谢谢使用:
#reshape by unstack per ID, concert series to one column DataFrame
df = df.set_index('ID').stack().to_frame('s')
#compare by 0
mask = df['s'].eq(0)
#helper column for consecutive 0 values
df['m'] = mask.groupby(level=0).cumsum()
#filter out 0 rows
df = df[~mask].reset_index()
#helper column for new columns names
df['g'] = df.groupby('ID')['m'].rank(method='dense').astype(int)
#create lists per groups, rehape and add prefix
df = (df.groupby(['ID','g'])['s'].apply(list)
.unstack()
.add_prefix('H')
.rename_axis(None, axis=1)
.reset_index())
print (df)
ID H1 H2
0 1 [2.5, 18.0] [4.0, 21.0, 7.0, 8.0, 10.0, 30.0, 40.0, 20.0]
1 4 [4.0, 18.0] NaN
2 7 [3.0, 78.0, 1.0] [2.0, 18.0, 80.0, 10.0, 11.0, 8.0]
3 21 [3.0, 18.0] NaN
4 41 [3.5, 18.0] [9.0, 10.0]
抱歉-早些时候被拉进了一个会议:我会这样处理:
df1 = df.groupby([df.index, "ID"]).agg(
lambda x: x.replace(0, np.nan).dropna().tolist())
# Create a sum of each list
df1['list_'] = df1.sum(axis=1)
print(df1['list_'])
0 [2.5, 18]
1 [4.0, 18]
2 [3.0, 78, 1]
3 [4.0, 21, 7, 8, 10, 30, 40, 20]
4 [3.0, 18]
5 [2.0, 18, 80, 10, 11, 8]
6 [3.5, 18, 9, 10]
Name: list_, dtype: object
然后使用交叉表使用cumcount和pivot创建计数器列。
# Create a row to use for columns
df1['count'] = 'H' + (df1.groupby('ID').cumcount() + 1).astype(str)
df1.reset_index(level=1,inplace=True)
final_ = pd.crosstab(df1["ID"],
df1["count"],
values=df1["list_"],
aggfunc="first").reset_index()
print(final_)
ID H1 H2
0 1 [2.5, 18] [4.0, 21, 7, 8, 10, 30, 40, 20]
1 4 [4.0, 18] NaN
2 7 [3.0, 78, 1] [2.0, 18, 80, 10, 11, 8]
3 21 [3.0, 18] NaN
4 41 [3.5, 18, 9, 10] NaN
我能看到的唯一痛点是,我的列表列是一个对象,不确定以后是否要对它执行进一步的操作。如果是这样的话,耶斯雷尔的解决方案将更合适
为遇到此问题的任何其他人编辑:
使用python的
.sum()
是列表连接最慢的方法之一,如果性能是一个问题,请参阅:如果有第三个重复的ID,那么是否有h3列?是的,行中有更多的ID条目,结尾有更多的列为什么41在h2中有值?@DataNearroil-因为18
和9
之间有3.5180901000
啊,但它与他的预期输出不匹配,所以我很困惑。他打了绿色勾,所以我猜是对的lol,我把我的答案放在这里以防万一。在我的答案中加上一句:“一如既往地感谢乔齐,你教会了我这么多东西!”!此解决方案即使提供了正确的响应,也会返回无序的“Hx”列。例如,H10H8H97。。。我尝试使用final\ux=final\ux.reindex(排序(final\ux.columns),axis=1),但没有任何success@user3043636尝试:(df1.groupby('ID').cumcount()+1).astype(str).str.zfill(2)
如果这不起作用,您需要按字母数字顺序排列列,这是Jezrael讽刺的回答。