我有一个包含三列字符串的数据框。我知道第三列中只有一个值对前两列的每个组合都有效。要清理数据,我必须按数据帧按前两列进行分组,并为每个组合选择第三列的最常用值。
我的代码:
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])
最后一行代码不起作用,它说“关键错误‘简称’”,如果我试图只按城市分组,那么我得到了一个断言错误。我能做什么来修复它?
对于agg
,lambba函数得到一个Series
,它没有'短名称'
属性。
stats.mode
返回一个由两个数组组成的元组,因此您必须在这个元组中获取第一个数组的第一个元素。
通过以下两个简单的更改:
source.groupby(['Country','City']).agg(lambda x: stats.mode(x)[0][0])
返回
Short name
Country City
Russia Sankt-Petersburg Spb
USA New-York NY
使用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
如果需要将其作为数据帧,请使用
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
的有用之处在于它总是返回一个序列,这使得它与agg
和apply
非常兼容,尤其是在重建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
如果您不关心返回哪个模式,只要它是其中一个,那么您将需要一个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
您还可以使用python中的statistics.mode
,但是。。。
source.groupby(['Country','City'])['Short name'].apply(statistics.mode)
Country City
Russia Sankt-Petersburg Spb
USA New-York NY
Name: Short name, dtype: object
…当必须处理多种模式时,它不能很好地工作;出现统计错误
。文件中提到了这一点:
如果数据为空,或者没有一个最常见的值,则会引发统计错误。
但是你可以自己看。。。
statistics.mode([1, 2])
# ---------------------------------------------------------------------------
# StatisticsError Traceback (most recent call last)
# ...
# StatisticsError: no unique mode; found 2 equally common values
您可以使用value\u counts()
获取计数序列,并获取第一行:
import pandas as pd
source = pd.DataFrame({'Country' : ['USA', 'USA', 'Russia','USA'],
'City' : ['New-York', 'New-York', 'Sankt-Petersburg', 'New-York'],
'Short name' : ['NY','New','Spb','NY']})
source.groupby(['Country','City']).agg(lambda x:x.value_counts().index[0])
如果你想在. agg()中执行其他agg函数,试试这个。
# Let's add a new col, account
source['account'] = [1,2,3,3]
source.groupby(['Country','City']).agg(mod = ('Short name', \
lambda x: x.value_counts().index[0]),
avg = ('account', 'mean') \
)
问题内容: 我有一个包含三个字符串列的数据框。我知道第三列中的唯一一个值对于前两个的每种组合都有效。为了清理数据,我必须按前两列按数据帧分组,并为每种组合选择第三列的最常用值。 我的代码: 最后一行代码不起作用,它显示“ Key error’Short name’”,如果我尝试仅按城市分组,则会收到AssertionError。我该如何解决? 问题答案: 你可以用来获取计数系列,并获取第一行:
问题内容: 从下面的数据中,我需要使用SQL Server 2005为每个链接ID选择最接近指定日期的记录: 因此,使用01/10/2010选择它们应返回: 我知道这是有可能的,但似乎无法绕开我的头脑(必须太接近一天的结束了:P)如果有人可以帮助或朝正确的方向轻轻推一下,将不胜感激! 编辑: 另外我也遇到了这个sql以获取最接近的日期: 但无法弄清楚如何正确地整合到查询中… 谢谢 问题答案: 你可
在MySql表中拥有以下数据: 我想选择唯一的unit_code(unit_code可以在表中的unit_code列中出现几次),日期为最大值且日期等于或小于今天的金额和日期。我在努力,但还没有接近结果。
我有一个熊猫数据框,格式如下: df: 现在我想将其分为两列,如下所示: 输出: 我想得到每一行的计数,如下所示。预期产出: 如何获得我的预期输出?我想找出每个“col2”值的最大计数?
我有这样的数据: 自然有许多地点和许多产品每个地点。我希望以这样的数据流结束: 我想出了最常见的方法,用这个。 在将其扩展到N个最常见的时,我可以创建另一个删除这些行的dataframe,再次运行该过程以获得第二个最常见的,并按位置将它们连接在一起。通过适当的列命名,可以将其放入循环中运行N次,每次迭代添加一个列。 然而,这将是非常缓慢的,因为它将划分和加入每个迭代。例如,我如何以更好的方式获得每
我刚刚过滤了一些数据,现在我有一个。csv文件,但我注意到我只需要选择具有最低价格的行: 例子: 在这个例子中,我只想得到第三行和第六行: 使用python,如何获得最终的表?