gpt4 book ai didi

python - GroupBy pandas DataFrame 并选择最常见的值

转载 作者:IT老高 更新时间:2023-10-28 20:21:54 26 4
gpt4 key购买 nike

我有一个包含三个字符串列的数据框。我知道第三列中唯一的一个值对于前两个的每个组合都是有效的。要清理数据,我必须按数据框按前两列分组,并为每个组合选择第三列的最常见值。

我的代码:

import pandas as pd
from scipy import stats

source = pd.DataFrame({'Country' : ['USA', 'USA', 'Russia','USA'],
'City' : ['New-York', 'New-York', 'Sankt-Petersburg', 'New-York'],
'Short name' : ['NY','New','Spb','NY']})

print source.groupby(['Country','City']).agg(lambda x: stats.mode(x['Short name'])[0])

最后一行代码不起作用,它显示“Key error 'Short name'”,如果我尝试仅按城市分组,则会收到 AssertionError。我能做些什么来解决它?

最佳答案

Pandas >= 0.16

pd.Series.mode 可用!

使用 groupby , GroupBy.agg , 并应用 pd.Series.mode每个组的功能:

source.groupby(['Country','City'])['Short name'].agg(pd.Series.mode)

Country City
Russia Sankt-Petersburg Spb
USA New-York NY
Name: Short name, dtype: object

如果需要将其作为 DataFrame,请使用

source.groupby(['Country','City'])['Short name'].agg(pd.Series.mode).to_frame()

Short name
Country City
Russia Sankt-Petersburg Spb
USA New-York NY

Series.mode 的有用之处在于它总是返回一个 Series,使其与 aggapply 非常兼容,尤其是在重建 groupby 输出。它也更快。

# Accepted answer.
%timeit source.groupby(['Country','City']).agg(lambda x:x.value_counts().index[0])
# Proposed in this post.
%timeit source.groupby(['Country','City'])['Short name'].agg(pd.Series.mode)

5.56 ms ± 343 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
2.76 ms ± 387 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

处理多种模式

Series.mode 在有多种模式时也能很好地工作:

source2 = source.append(
pd.Series({'Country': 'USA', 'City': 'New-York', 'Short name': 'New'}),
ignore_index=True)

# Now `source2` has two modes for the
# ("USA", "New-York") group, they are "NY" and "New".
source2

Country City Short name
0 USA New-York NY
1 USA New-York New
2 Russia Sankt-Petersburg Spb
3 USA New-York NY
4 USA New-York New

source2.groupby(['Country','City'])['Short name'].agg(pd.Series.mode)

Country City
Russia Sankt-Petersburg Spb
USA New-York [NY, New]
Name: Short name, dtype: object

或者,如果您想为每种模式单独设置一行,您可以使用 GroupBy.apply :

source2.groupby(['Country','City'])['Short name'].apply(pd.Series.mode)

Country City
Russia Sankt-Petersburg 0 Spb
USA New-York 0 NY
1 New
Name: Short name, dtype: object

如果您不关心返回哪个模式,只要它是其中之一,那么您将需要一个调用 mode 并提取第一个结果的 lambda .

source2.groupby(['Country','City'])['Short name'].agg(
lambda x: pd.Series.mode(x)[0])

Country City
Russia Sankt-Petersburg Spb
USA New-York NY
Name: Short name, dtype: object

替代(不)考虑

您也可以使用statistics.mode来自python,但是...

source.groupby(['Country','City'])['Short name'].apply(statistics.mode)

Country City
Russia Sankt-Petersburg Spb
USA New-York NY
Name: Short name, dtype: object

...在处理多种模式时效果不佳;引发了 StatisticsError。文档中提到了这一点:

If data is empty, or if there is not exactly one most common value, StatisticsError is raised.

但你可以自己看看……

statistics.mode([1, 2])
# ---------------------------------------------------------------------------
# StatisticsError Traceback (most recent call last)
# ...
# StatisticsError: no unique mode; found 2 equally common values

关于python - GroupBy pandas DataFrame 并选择最常见的值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15222754/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com