Python 熊猫中多个列的最常见值
我有一系列不规则列中的数据,我需要使用pandas从跨多个列的分割部分确定最常见的值。我的意思的一个例子是,如果我有我的同事每天午餐吃什么奶酪的信息:Python 熊猫中多个列的最常见值,python,pandas,statistics,Python,Pandas,Statistics,我有一系列不规则列中的数据,我需要使用pandas从跨多个列的分割部分确定最常见的值。我的意思的一个例子是,如果我有我的同事每天午餐吃什么奶酪的信息: Idx Name Cheese1 Cheese2 Cheese3 0 Evan Gouda NaN NaN 1 John Cheddar Havarti Blue 2 Evan Cheddar Gouda NaN 3 John Havarti Swiss
Idx Name Cheese1 Cheese2 Cheese3
0 Evan Gouda NaN NaN
1 John Cheddar Havarti Blue
2 Evan Cheddar Gouda NaN
3 John Havarti Swiss NaN
我正在寻找某种功能,它将提供生成的透视表:
Name Cheese Pct
Evan Gouda .66
John Havarti .4
我也不知道每次运行脚本时需要包含多少列,只是它们都是“Cheese”+索引格式。如果John第二天带着四块奶酪出现,我需要添加第四列,分析脚本需要能够处理这一点
import io
import pandas as pd
data = io.StringIO("""\
Idx Name Cheese1 Cheese2 Cheese3
0 Evan Gouda NaN NaN
1 John Cheddar Havarti Blue
2 Evan Cheddar Gouda NaN
3 John Havarti Swiss NaN
4 Rick NaN NaN NaN
""")
df = pd.read_csv(data, delim_whitespace=True)
def top_cheese(g):
cheese_cols = [col for col in g.columns if col.startswith('Cheese')]
try:
out = (g[cheese_cols].stack().value_counts(normalize=True)
.reset_index().iloc[0])
out.index = ['Cheese', 'Pct']
return out
except IndexError:
return pd.Series({'Cheese': 'None', 'Pct': 0})
output = df.groupby('Name').apply(top_cheese)
print(output)
输出:
Cheese Pct
Name
Evan Gouda 0.666667
John Havarti 0.400000
Rick None 0.000000
最近,我一直在使用
R
,在那里我会像这样解决这个问题:
库(data.table)
图书馆(dplyr)
图书馆(tidyr)
x%
按(姓名、奶酪)%>%分组
总结(n=n())%>%
分组单位(名称)%>%
突变(p=n/和(n))%>%
过滤器(p==最大值(p))%>%
选择(-n)
哪些产出:
Name Cheese p
1 Evan Gouda 0.666667
4 John Havarti 0.400000
Name奶酪p
(chr)(chr)(dbl)
1埃文·古达0.667
2约翰·哈瓦蒂4000000
我很想看看熊猫身上类似的东西会是什么样子。这就是我想到的:
import io
import pandas as pd
x = pd.read_csv(io.StringIO('''
Idx Name Cheese1 Cheese2 Cheese3
0 Evan Gouda NaN NaN
1 John Cheddar Havarti Blue
2 Evan Cheddar Gouda NaN
3 John Havarti Swiss NaN'''), delim_whitespace=True)
tidy = pd.melt(x, ['Idx', 'Name'], value_name='Cheese').dropna()
tidy = tidy.groupby(['Name', 'Cheese']).size().reset_index(name='n')
tidy['p'] = tidy.groupby('Name')['n'].transform(lambda n: n/sum(n))
tidy[tidy['p'] == tidy.groupby('Name')['p'].transform('max')].drop('n', 1)
哪些产出:
Name Cheese p
1 Evan Gouda 0.666667
4 John Havarti 0.400000
当然没有
R
那么干净,但也许更熟悉熊猫的人可以考虑如何改进这一点。你错过了一个机会来命名功能big_cheese
这是可行的,但当所有人都有相同的最普通的奶酪时,它就会破裂。相反,它将名称作为列标题而不是索引提供。有什么办法可以解决这个问题吗?我通过使用try-except语句来获得索引或列名来解决这个问题,但这是janky,如果有人有更好的解决方案,我希望有更好的解决方案。这很有效。我其实并不在乎液滴,但不管怎样,谢谢你把它放在那里!我还将函数改为try/except返回语句,因为我的一些同事根本不带奶酪,所以他们所有的行都是空的。我包括:除了:return pd.Series(data=[0],index=['None'])。reset_index()
非常有效。最后一次更新。更改.iloc[[0]]
的.iloc[0]
将返回一个系列
,并避免降低级别。将索引移动到top\u cheese()
中。添加了try/except
逻辑。瑞克怎么了?没有奶酪?哦,人性!