我有一个包含未知数量的pandas数据帧的字典。每个数据框都包含一组始终存在的列(user_id)和一组可能存在或可能不存在的列。所有数据帧都具有相同的行数和顺序。每个单元格的内容都是一个列表(对于我感兴趣的列)。
简化示例:
df['first'] = pd.DataFrame( {'user_ID': [1, 2, 3],
'col1': [[1], [2,3], [3]],
'col2': [[3], [3], [3,1]],
'col3': [[], [1,2,3], [3,1]]} )
df['second'] = pd.DataFrame( {'user_ID': [1, 2, 3],
'col1': [[1, 2], [3], [3]],
'col3': [[1], [2,3], [3]],
'col4': [[3], [3], [3,1]] })
df['last'] = pd.DataFrame( {'user_ID': [1, 2, 3],
'col1': [[1], [2,3], [3]],
'col2': [[3], [3], [3,1]],
'col5': [[], [1,2,3], [3,1]]} )
他们看起来像:
col1 col2 col3 user_ID
0 [1] [3] [] 1
1 [2, 3] [3] [1, 2, 3] 2
2 [3] [3, 1] [3, 1] 3
col1 col3 col4 user_ID
0 [1, 2] [1] [3] 1
1 [3] [2, 3] [3] 2
2 [3] [3] [3, 1] 3
col1 col2 col5 user_ID
0 [1] [3] [] 1
1 [2, 3] [3] [1, 2, 3] 2
2 [3] [3, 1] [3, 1] 3
如何将所有这些数据框合并到一个数据框中,其中所有非user_ID的列都已合并,因此内容会附加到列表中?
结果应如下(每个列表中元素的顺序无关紧要):
col1 col2 col3 col4 col5 user_ID
0 [1, 1, 2, 1] [3, 3] [1] [3] [] 1
1 [2, 3, 3, 2, 3] [3, 3] [1, 2, 3, 2, 3] [2] [1, 2, 3] 2
2 [3, 3, 3] [3, 1, 3, 1] [3, 1, 3] [3, 1] [3, 1] 3
我设法连接数据帧,但我仍然需要合并生成的列。
for dfName in ['first', 'second', 'last']:
df[dfName] = df[dfName].drop(['user_ID'], axis=1)
merged = pd.concat(df, axis=1, keys=['first', 'second', 'last'])
print(merged)
输出:
first second last \
col1 col2 col3 col1 col3 col4 col1 col2
0 [1] [3] [] [1, 2] [1] [3] [1] [3]
1 [2, 3] [3] [1, 2, 3] [3] [2, 3] [3] [2, 3] [3]
2 [3] [3, 1] [3, 1] [3] [3] [3, 1] [3] [3, 1]
col5
0 []
1 [1, 2, 3]
2 [3, 1]
有什么想法吗?
答案 0 :(得分:2)
这有点牵扯,但你需要for item in soup.find_all('p', id=re.compile('^test')):
。首先,使用df.groupby
并加入它们。然后使用pd.concat
替换NaN
,最后使用groupby和sum。
df.applymap
由于Maarten Fabré,效率略有提高。
如果您拥有未知数量的数据框,可以将它们放在In [673]: pd.concat([df1, df2, df3], 0)\
.applymap(lambda x: [] if x != x else x)\
.groupby('user_ID', as_index=False).sum()
Out[673]:
user_ID col1 col2 col3 col4 col5
0 1 [1, 1, 2, 1] [3, 3] [1] [3] []
1 2 [2, 3, 3, 2, 3] [3, 3] [1, 2, 3, 2, 3] [3] [1, 2, 3]
2 3 [3, 3, 3] [3, 1, 3, 1] [3, 1, 3] [3, 1] [3, 1]
或list
中,并将其传递给dict
:
pd.concat
答案 1 :(得分:1)
如果不是df.groupby('user_ID').sum()
值,则可以使用nan
,这会导致所有列与col1
分开。
要解决这个问题,你可以使用这种相当丑陋的方法
pd.concat((df0, df1, df2)).fillna(-1).applymap(lambda x: x if x != -1 else []).groupby('user_ID').sum()
我不得不诉诸fillna(-1).applymap(...)
,因为您似乎无法将[]
直接分配给某个项目。如果有人有更好的建议,请告诉我
使用@ COLDSPEED将NaN
与NaN
进行比较的技巧
pd.concat((df0, df1, df2)).applymap(lambda x: x if x == x else []).groupby('user_ID').sum()
更轻松
如果您想将user_ID
作为列,n而不是索引,只需添加.reset_index()