我想在密钥上对数据帧进行分组,在这种情况下是clientid。并将每个键的所有列连接成每个键的一个长行。
e.g。
clientid, name, age, company
1, tom, 31, awesome
1, jen, 26, argos
2, bob, 18, hmv
3, ted, 12, mcdonalds
4, sarah,30, MnS
4, mike, 52, Mns
4, luke, 75, argos
想要的结果
clientid, name, age, company, name, age, company, name, age, company
1, tom, 31, awesome, jen, 26, argos,
2, bob, 18, hmv,
3, ted, 12, mcdonadls,
4, sarah,30, MnS, mike, 52, MnS, luke, 75, argos,
给出了类似的问题和解决方案
df_info = df1.groupby('clientid')['info'].unique().apply(pd.Series).reset_index()
info_len = len([col for col in df_info if str(col).isdigit()])
df_info.columns = ['clientid'] + ['info'] * info_len
df_info
但我无法找到如何将其应用于多列
答案 0 :(得分:0)
这带有一个健康警告,因为你失去了大熊猫的力量,让结构允许你分组,优秀的性能,强大而干净的语法(所以在某种意义上它是你的特色)不能轻易做到这一点!)......而且它不是很难吃。
所以我强烈建议不要这样做,因为几乎可以肯定有更好的方法去做你正在做的事......
我认为你需要将clientid分组,然后提取这些字符串......
In [11]: df1 = df.set_index('clientid')
In [12]: df1
Out[12]:
name age company
clientid
1 tom 31 awesome
1 jen 26 argos
2 bob 18 hmv
3 ted 12 mcdonalds
4 sarah 30 MnS
4 mike 52 Mns
4 luke 75 argos
In [13]: g = df1.groupby(df1.index)
我可能会考虑在每个群组中使用to_csv
:
In [14]: g.apply(lambda x: x.to_csv(header=False, index=False, line_terminator=','))
Out[14]:
clientid
1 tom,31,awesome,jen,26,argos,
2 bob,18,hmv,
3 ted,12,mcdonalds,
4 sarah,30,MnS,mike,52,Mns,luke,75,argos,
dtype: object
另一种方法是申请:
In [15]: g.apply(lambda x: pd.concat([row for _, row in x.iterrows()]).values)
Out[15]:
clientid
1 [tom, 31, awesome, jen, 26, argos]
2 [bob, 18, hmv]
3 [ted, 12, mcdonalds]
4 [sarah, 30, MnS, mike, 52, Mns, luke, 75, argos]
dtype: object
你必须稍微破解一下以获得正确的标题:
In [16]: list(df1.columns) * g.apply(len).max()
Out[16]: ['name', 'age', 'company', 'name', 'age', 'company', 'name', 'age', 'company']
因此,您可以执行以下操作:
In [21]: s = g.apply(lambda x: pd.concat([row for _, row in x.iterrows()]).values).apply(lambda row: ','.join([str(x) for x in row]))
In [22]: s.name = ','.join(list(df1.columns) * g.apply(len).max())
In [23]: s.to_frame().to_csv(quotechar=" ") # Note: this is a hack since quoting=0 seems to be ignored
Out[23]: 'clientid, name,age,company,name,age,company,name,age,company \n1, tom,31,awesome,jen,26,argos \n2, bob,18,hmv \n3, ted,12,mcdonalds \n4, sarah,30,MnS,mike,52,Mns,luke,75,argos \n'
答案 1 :(得分:0)
我尝试了几种方法,并提出了一些改进版的安迪,我发现它很有效。
grouped = df1.groupby('clientid')
flattenedSeries = grouped.apply(lambda x: x.to_csv(header=False, index=False, line_terminator=','))
flattenedSeries = pd.DataFrame(flattenedSeries, columns=['data'])
ready = flattenedSeries['data'].apply(lambda x: pd.Series(x.split(',')))
创建新的列标题
newcolumns = list(df1.columns) * grouped.apply(len).max()
添加神秘列以匹配pd.Series中创建的空白(x.split(','))
newcolumns = newcolumns + ['extra']
ready.columns = newcolumns
为索引提供一个类型以帮助将来合并
ready.index= ready.index.astype('int64')
如果在任何列数据中使用了行终止符,则可以更改行终止符。