Python计数与概率

3

我有以下数据:

Name    Item
peter   apple
peter   apple
Ben     banana
peter   banana

我想要打印
frequency of what peter eat :
apple 2 
banana 1 

这是我的代码

u, count = np.unique(data['Item'], return_counts=True)

process = u[np.where(data['Name']= 'peter')[0]]

process2 = dict(Counter(process))
print "Item\frequency"

for k, v in process2.items():
print '{0:.0f}\t{1}'.format(k,v)

但是出现了错误。 我还想计算彼得下次吃苹果的概率,但我没有任何想法,有什么建议吗?


错误:关键词不能作为表达式。 - aaaabbbb
data是什么?Pandas DataFrame? Numpy记录数组?你正在哪一行遇到错误? - Anand S Kumar
我使用了Pandas来读取我的数据文件。 - aaaabbbb
process = u[np.where(data['Name'] == 'peter')[0]]这里有错误。 - aaaabbbb
4个回答

2
您遇到的错误如其他答案所示,您不能将data ['Name'] ='peter'用作函数参数,您实际上打算使用-np.where(data['Name']=='peter')
但是,鉴于您正在使用pandas,而且我猜测data是一个pandas DataFrame。在这种情况下,您真正想要的可以使用DataFrame.groupby来实现。例如-
data[data['Name']=='peter'].groupby('Item').count()

演示 -

In [7]: data[data['Name']=='peter'].groupby('Item').count()
Out[7]:
        Name
Item
apple      2
banana     1

如果您希望将此内容循环打印,您可以使用 -
df = data[data['Name']=='peter'].groupby('Item').count()
for fruit,count in df['Name'].iteritems():
    print('{0}\t{1}'.format(fruit,count))

示例 -

In [24]: df = data[data['Name']=='peter'].groupby('Item').count()

In [25]: for fruit,count in df['Name'].iteritems():
   ....:     print('{0}\t{1}'.format(fruit,count))
   ....:
apple   2
banana  1

针对OP遇到的更新问题,他遇到了以下错误 -

TypeError: invalid type comparison

这种情况是由于在OP的真实数据中,该列具有数字值(float / int),但OP正在将值与字符串进行比较,因此出现错误。例如 -

In [30]: df
Out[30]:
   0  1
0  1  2

In [31]: df[0]=='asd'
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-31-e7bacd79d320> in <module>()
----> 1 df[0]=='asd'

C:\Anaconda3\lib\site-packages\pandas\core\ops.py in wrapper(self, other, axis)
    612
    613             # scalars
--> 614             res = na_op(values, other)
    615             if np.isscalar(res):
    616                 raise TypeError('Could not compare %s type with Series'

C:\Anaconda3\lib\site-packages\pandas\core\ops.py in na_op(x, y)
    566                 result = getattr(x, name)(y)
    567                 if result is NotImplemented:
--> 568                     raise TypeError("invalid type comparison")
    569             except (AttributeError):
    570                 result = op(x, y)

TypeError: invalid type comparison

如果您的列是数字类型,应该与数字值进行比较,而不是字符串。

是的,它是一个 pandas DataFrame,请使用我提供的方法。 - Anand S Kumar
谢谢,但是在“data[data['Name']=='peter'].groupby('Item').count()”这一行出现了“无效类型比较”的错误。 - aaaabbbb
这个代码会给你什么结果 - print(data[data['Name']=='peter']) - Anand S Kumar
我不确定是否相关,但真实数据不是“apple”和“peter”,而是一些数字ID,例如“123456”,这是导致错误的原因吗? - aaaabbbb
1
可以使用真实数据而不是“peter”。 - Anand S Kumar
显示剩余7条评论

2
你可以按名称分组并使用 value_counts
In [11]: df.groupby("Name")["Item"].value_counts()
Out[11]:
Name
Ben    banana    1
peter  apple     2
       banana    1
dtype: int64

潜在的情况下,您可以将它们拆成列:

In [12]: df.groupby("Name")["Item"].value_counts().unstack(1)
Out[12]:
       apple  banana
Name
Ben      NaN       1
peter      2       1

In [13]: res = df.groupby("Name")["Item"].value_counts().unstack(1).fillna(0)

In [13]: res
Out[13]:
       apple  banana
Name
Ben        0       1
peter      2       1

要获取概率,请除以总和:

In [14]: res = res.div(res.sum(axis=1), axis=0)

In [15]: res
Out[15]:
          apple    banana
Name
Ben    0.000000  1.000000
peter  0.666667  0.333333

下一次彼得吃苹果的概率:

In [16]: res.loc["peter", "apple"]
Out[16]: 0.66666666666666663

0

我对Pandas或NumPy不是非常熟悉,但我能看到的一个问题是:

data['Name'] = 'peter'

是一个赋值语句。

而你可能想要检查相等:

data['Name'] == 'peter'

此外,除非您在粘贴代码时弄乱了缩进,否则您需要缩进for语句的主体,否则一旦解决了这个问题,您会发现另一个错误。
for k, v in process2.items():
    print '{0:.0f}\t{1}'.format(k,v)

谢谢您的回答,我进行了更改,但出现了“无效类型比较”的错误。 - aaaabbbb
数据["Name"]的类型是什么?尝试使用print typeof(data["Name"])打印。 - Jacob Ritchie
<class 'pandas.core.series.Series'> - aaaabbbb

0

如果您不是非常固执于使用 numpy:

import collections
import csv

data = collections.defaultdict(lambda: collections.defaultdict(int))
with open('path/to/file') as infile:
    infile.readline()  # fet rid of the header
    for name, food in csv.reader(infile):
        data[name][food] += 1

for name, d in data.iteritems():
    print("frequency of what" name, "ate:")
    total = float(sum(d.values()))
    for food, count in d.iteritems():
        print(food, count, "probability:", count/total)

谢谢回答,但我需要使用numpy。无论如何还是谢谢 :) - aaaabbbb

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接