Pandas - 列中 groupby 之后的 Concat 字符串,忽略 NaN,忽略重复项
Posted
技术标签:
【中文标题】Pandas - 列中 groupby 之后的 Concat 字符串,忽略 NaN,忽略重复项【英文标题】:Pandas - Concat strings after groupby in column, ignore NaN, ignore duplicates 【发布时间】:2017-01-11 00:40:39 【问题描述】:根据查询,我的 DF 可以有一个带有字符串的列或一个带有 NaN 的列。
例如:
ID grams Projects
0 891 4.0 NaN
1 725 9.0 NaN
或
ID grams Projects
0 890 1.0 P1, P2
1 724 1.0 P1
2 880 1.0 P1, P2
3 943 1.0 P1
4 071 1.0 P1
我可以处理其中一个,但是当我尝试创建一个通用的函数时,我失败了。最后我需要忽略 NaN,因为我将此 DF 作为 JSON 响应发送,而 NaN 给了我无效的格式。
我现在的做法是:
#When Projects is a string
df['Projects'] = _df.groupby("ID")['External_Id'].apply(lambda x: ",".join(x))
#When Projects is NaN
df['Projects'] = _df.groupby("ID")['External_Id'].apply(lambda x: "")
我尝试使用fillna()
并检查 'x' 的 dtype,但它总是返回为 object,所以我无法检查它是否是 str 或 NaN
此外,“项目”列的结果不应允许重复。某些按 ID 分组的行包含重要信息,这些信息将被汇总(“克”),但“External_Id”不应出现多次。 例如:
ID grams External_Id
0 890 1.0 P1
1 890 1.0 P2
2 890 1.0 P2
3 724 1.0 P1
4 724 1.0 P1
结果应该是
ID grams Projects
0 890 3.0 P1, P2
1 724 2.0 P1
不是
ID grams Projects
0 890 1.0 P1, P2, P2
1 724 1.0 P1, P1
【问题讨论】:
如果我理解正确,您需要检测列是否有 NaN? 是的,你是对的。如果列有 NaN,我想返回一个空字符串 (""),因为它在 JSON 对象中无效。 “忽略重复项”是什么意思?它在标题中,但似乎从问题的正文中消失了。 你说得对,我忘了解释。我会添加到正文中。我基本上有一些具有相同 ID 和相同项目的行。行上的其他信息对于计数/分析很重要,但例如,项目在连接时应该只出现一次,而不是“P1,P1,P1 ...”。 所有的 NaN 是否都与同一个项目有关?如果你能举个输入数据的例子就好了 【参考方案1】:假设你开始
In [37]: df = pd.DataFrame('a': [1, 1, 2, 2], 'b': [1, None, 2, 4], 'c': ['foo', 'sho', 'sha', 'bar'])
In [43]: df
Out[43]:
a b c
0 1 1.0 foo
1 1 NaN foo
2 2 2.0 sha
3 2 4.0 bar
然后您可以将相同的函数应用于b
或c
,同时处理 NaN 和重复项:
In [44]: df.b.groupby(df.a).apply(lambda x: '' if x.isnull().any() else ','.join(set(x.astype(str).values)))
Out[44]:
a
1
2 2.0,4.0
dtype: object
In [45]: df.c.groupby(df.a).apply(lambda x: '' if x.isnull().any() else ','.join(set(x.astype(str).values)))
Out[45]:
a
1 foo
2 sha,bar
dtype: object
【讨论】:
这就像一个魅力。我尝试了这个.isnull()
,但我不知道我可以使用这个.any()
也不是astype()
(我正在使用.dtype 进行验证)......该设置很好地避免了重复。谢谢【参考方案2】:
我认为这应该会有所帮助:
import numpy
df_new = df.replace(numpy.nan,' ', regex=True)
编辑:
我认为这个solution 可以为你工作(就像@Ami 的答案的替代品。
【讨论】:
这很好用,但这就是我忽略重复项的意思。它现在返回一堆逗号。例如:" , , , , , , , , " 对不起,我想我不明白,你想输出什么? 抱歉,@vlad.rad,我编辑了我的问题。当没有项目时,我只想拥有“”,而不是“, , , , , , , ,” 或重复项目。我忘了在正文中添加。 我想我只需要在这个答案中使用 set() .apply(lambda x: ",".join(set(x))) 我找到了关于堆栈溢出的另一个讨论,我已将链接粘贴到我编辑的答案中。祝你好运!以上是关于Pandas - 列中 groupby 之后的 Concat 字符串,忽略 NaN,忽略重复项的主要内容,如果未能解决你的问题,请参考以下文章