Pandas Dataframe GroupBy Agg - LAMBDA - single values go to preexisting or new lists and preexisting lists fusion(Pandas Dataframe Groupby Agg-Lambda-Single Value转到先前存在的或新的列表与先前存在的列表融合)
问题描述
我有此DataFrame to groupby密钥:
df = pd.DataFrame({
'key': ['1', '1', '1', '2', '2', '3', '3', '4', '4', '5'],
'data1': [['A', 'B', 'C'], 'D', 'P', 'E', ['F', 'G', 'H'], ['I', 'J'], ['K', 'L'], 'M', 'N', 'O']
'data2': [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
})
df
我想将GROUPBY KEY和SUM数据设为2,这部分可以。 但是关于数据1,我想:
- 如果列表尚不存在:
- 密钥不重复时,单个值不会更改
- 分配给键的单个值合并到一个新列表中
- 如果列表已存在:
- 其他单个值被追加到它后面
- 附加其他列表值
生成的DataFrame应为:
dfgood = pd.DataFrame({
'key': ['1', '2', '3', '4', '5'],
'data1': [['A', 'B', 'C', 'D', 'P'], ['F', 'G', 'H', 'E'], ['I', 'J', 'K', 'L'], ['M', 'N'], 'O']
'data2': [6, 9, 13, 17, 10]
})
dfgood
事实上,我并不真正关心data1值进入列表的顺序,它也可以是将它们保持在一起的任何结构,甚至可以是带分隔符的字符串或集合,如果这样做更容易让它按照您认为最好的方式进行的话。
我想了两个解决方案:
- 往那边走:
dfgood = df.groupby('key', as_index=False).agg({
'data1' : lambda x: x.iloc[0].append(x.iloc[1]) if type(x.iloc[0])==list else list(x),
'data2' : sum,
})
dfgood
由于x.iloc[1]
中的index out of range
无法工作。
我也试过了,因为在this link上的问题中的另一个groupby中,data1是这样组织的:
dfgood = df.groupby('key', as_index=False).agg({
'data1' : lambda g: g.iloc[0] if len(g) == 1 else list(g)),
'data2' : sum,
})
dfgood
但它是从先前存在的列表或值创建新列表,而不是将数据追加到现有列表。
- 另一种方式,但是我觉得比较复杂,应该有更好或者更快的解决方案:
- 使用
apply
, 将data1列表和单个值转换为单个系列
- 使用
wide_to_long
为每个键保留单个值, - 然后分组申请:
- 使用
dfgood = df.groupby('key', as_index=False).agg({
'data1' : lambda g: g.iloc[0] if len(g) == 1 else list(g)),
'data2' : sum,
})
dfgood
我认为我的问题是我不知道如何正确使用lambdas,并且我尝试了像上一个示例中的x.iloc[1]
这样愚蠢的事情。我已经看了很多关于lambdas的教程,但在我的脑海中仍然是模糊不清的。
推荐答案
存在带标量的问题组合列表,可能的解决方案是先从标量创建列表,然后在groupby.agg
中将其展平:
dfgood = (df.assign(data1 = df['data1'].apply(lambda y: y if isinstance(y, list) else [y]))
.groupby('key', as_index=False).agg({
'data1' : lambda x: [z for y in x for z in y],
'data2' : sum,
})
)
print (dfgood)
key data1 data2
0 1 [A, B, C, D, P] 6
1 2 [E, F, G, H] 9
2 3 [I, J, K, L] 13
3 4 [M, N] 17
4 5 [O] 10
另一个想法是使用flatten
函数只拼合列表,而不是字符串:
#https://stackoverflow.com/a/5286571/2901002
def flatten(foo):
for x in foo:
if hasattr(x, '__iter__') and not isinstance(x, str):
for y in flatten(x):
yield y
else:
yield x
dfgood = (df.groupby('key', as_index=False).agg({
'data1' : lambda x: list(flatten(x)),
'data2' : sum}))
这篇关于Pandas Dataframe Groupby Agg-Lambda-Single Value转到先前存在的或新的列表与先前存在的列表融合的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:Pandas Dataframe Groupby Agg-Lambda-Single Value转到先前存在的或新的列表与先前存在的列表融合
基础教程推荐
- 如何在 Python 中检测文件是否为二进制(非文本)文 2022-01-01
- 使用 Google App Engine (Python) 将文件上传到 Google Cloud Storage 2022-01-01
- 如何在Python中绘制多元函数? 2022-01-01
- 将 YAML 文件转换为 python dict 2022-01-01
- 症状类型错误:无法确定关系的真值 2022-01-01
- 合并具有多索引的两个数据帧 2022-01-01
- Python 的 List 是如何实现的? 2022-01-01
- 哪些 Python 包提供独立的事件系统? 2022-01-01
- 使用Python匹配Stata加权xtil命令的确定方法? 2022-01-01
- 使 Python 脚本在 Windows 上运行而不指定“.py";延期 2022-01-01