鉴于以下DataFrame,我尝试汇总'A'
和'C'
列。对于'A'
,计算字符串的唯一外观,对于'C'
,对值求和。
当'A'
中的某些样本实际上是这些字符串的列表时,就会出现问题。
这是一个简化的示例:
df = pd.DataFrame({'ID': [1, 1, 1, 1, 1, 2, 2, 2],
'A' : ['a', 'a', 'a', 'b', ['b', 'c', 'd'], 'a', 'a', ['a', 'b', 'c']],
'C' : [1, 2, 15, 5, 13, 6, 7, 1]})
df
Out[100]:
ID A C
0 1 a 1
1 1 a 2
2 1 a 15
3 1 b 5
4 1 [b, c, d] 13
5 2 a 6
6 2 a 7
7 2 [a, b, c] 1
aggs = {'A' : lambda x: x.nunique(dropna=True),
'C' : 'sum'}
# This will result an error: TypeError: unhashable type: 'list'
agg_df = df.groupby('ID').agg(aggs)
我想要以下输出:
print(agg_df)
A C
ID
1 4 36
2 3 14
之所以这样,是因为'ID' = 1
有'a', 'b', 'c' and 'd
',而'ID' = 2
有'a', 'b', 'c'
。
答案 0 :(得分:1)
一种解决方案是将您的问题分成两部分。首先,将数据框展平以确保df['A']
仅包含字符串。然后串联几个GroupBy
操作。
您可以使用itertools.chain
和numpy.repeat
来适当地链接和重复值。
from itertools import chain
A = df['A'].apply(lambda x: [x] if not isinstance(x, list) else x)
lens = A.map(len)
res = pd.DataFrame({'ID': np.repeat(df['ID'], lens),
'A': list(chain.from_iterable(A)),
'C': np.repeat(df['C'], lens)})
print(res)
# A C ID
# 0 a 1 1
# 1 a 2 1
# 2 a 15 1
# 3 b 5 1
# 4 b 13 1
# 4 c 13 1
# 4 d 13 1
# 5 a 6 2
# 6 a 7 2
# 7 a 1 2
# 7 b 1 2
# 7 c 1 2
agg_df = pd.concat([res.groupby('ID')['A'].nunique(),
df.groupby('ID')['C'].sum()], axis=1)
print(agg_df)
# A C
# ID
# 1 4 36
# 2 3 14