Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/311.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 熊猫中多个列的最常见值_Python_Pandas_Statistics - Fatal编程技术网

Python 熊猫中多个列的最常见值

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

我有一系列不规则列中的数据,我需要使用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     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
逻辑。瑞克怎么了?没有奶酪?哦,人性!