Python pandas 忽略 NaN 的唯一值
Python pandas unique value ignoring NaN
我想在 groupby
聚合中使用 unique
,但我不想在 unique
结果中使用 nan
。
示例数据框:
df = pd.DataFrame({'a': [1, 2, 1, 1, np.nan, 3, 3], 'b': [0,0,1,1,1,1,1],
'c': ['foo', np.nan, 'bar', 'foo', 'baz', 'foo', 'bar']})
a b c
0 1.0000 0 foo
1 2.0000 0 NaN
2 1.0000 1 bar
3 1.0000 1 foo
4 nan 1 baz
5 3.0000 1 foo
6 3.0000 1 bar
和 groupby
:
df.groupby('b').agg({'a': ['min', 'max', 'unique'], 'c': ['first', 'last', 'unique']})
其结果为:
a c
min max unique first last unique
b
0 1.0000 2.0000 [1.0, 2.0] foo foo [foo, nan]
1 1.0000 3.0000 [1.0, nan, 3.0] bar bar [bar, foo, baz]
但我想要没有 nan
:
a c
min max unique first last unique
b
0 1.0000 2.0000 [1.0, 2.0] foo foo [foo]
1 1.0000 3.0000 [1.0, 3.0] bar bar [bar, foo, baz]
我该怎么做?当然,我有几个列要聚合,每个列都需要不同的聚合函数,所以我不想一个一个地进行 unique
聚合,并且与其他聚合分开。
2020 年 11 月 23 日更新
这个答案很糟糕,不要使用这个。请参考@IanS的回答
早些时候
尝试ffill
df.ffill().groupby('b').agg({'a': ['min', 'max', 'unique'], 'c': ['first', 'last', 'unique']})
c a
first last unique min max unique
b
0 foo foo [foo] 1.0 2.0 [1.0, 2.0]
1 bar bar [bar, foo, baz] 1.0 3.0 [1.0, 3.0]
如果 Nan 是组中的第一个元素,则上述解法失效。
定义函数:
def unique_non_null(s):
return s.dropna().unique()
然后在聚合中使用它:
df.groupby('b').agg({
'a': ['min', 'max', unique_non_null],
'c': ['first', 'last', unique_non_null]
})
这将满足您的需要:
df.fillna(method='ffill').groupby('b').agg({'a': ['min', 'max', 'unique'], 'c': ['first', 'last', 'unique']})
因为你使用了min
,max
和unique
重复的值与你无关。
您可以使用下面的代码,
df.apply(lambda x: len(x.dropna().unique()))
我想在 groupby
聚合中使用 unique
,但我不想在 unique
结果中使用 nan
。
示例数据框:
df = pd.DataFrame({'a': [1, 2, 1, 1, np.nan, 3, 3], 'b': [0,0,1,1,1,1,1],
'c': ['foo', np.nan, 'bar', 'foo', 'baz', 'foo', 'bar']})
a b c
0 1.0000 0 foo
1 2.0000 0 NaN
2 1.0000 1 bar
3 1.0000 1 foo
4 nan 1 baz
5 3.0000 1 foo
6 3.0000 1 bar
和 groupby
:
df.groupby('b').agg({'a': ['min', 'max', 'unique'], 'c': ['first', 'last', 'unique']})
其结果为:
a c
min max unique first last unique
b
0 1.0000 2.0000 [1.0, 2.0] foo foo [foo, nan]
1 1.0000 3.0000 [1.0, nan, 3.0] bar bar [bar, foo, baz]
但我想要没有 nan
:
a c
min max unique first last unique
b
0 1.0000 2.0000 [1.0, 2.0] foo foo [foo]
1 1.0000 3.0000 [1.0, 3.0] bar bar [bar, foo, baz]
我该怎么做?当然,我有几个列要聚合,每个列都需要不同的聚合函数,所以我不想一个一个地进行 unique
聚合,并且与其他聚合分开。
2020 年 11 月 23 日更新
这个答案很糟糕,不要使用这个。请参考@IanS的回答
早些时候
尝试ffill
df.ffill().groupby('b').agg({'a': ['min', 'max', 'unique'], 'c': ['first', 'last', 'unique']})
c a first last unique min max unique b 0 foo foo [foo] 1.0 2.0 [1.0, 2.0] 1 bar bar [bar, foo, baz] 1.0 3.0 [1.0, 3.0]
如果 Nan 是组中的第一个元素,则上述解法失效。
定义函数:
def unique_non_null(s):
return s.dropna().unique()
然后在聚合中使用它:
df.groupby('b').agg({
'a': ['min', 'max', unique_non_null],
'c': ['first', 'last', unique_non_null]
})
这将满足您的需要:
df.fillna(method='ffill').groupby('b').agg({'a': ['min', 'max', 'unique'], 'c': ['first', 'last', 'unique']})
因为你使用了min
,max
和unique
重复的值与你无关。
您可以使用下面的代码,
df.apply(lambda x: len(x.dropna().unique()))