首页 > 解决方案 > 如何在熊猫数据框中构建项目频率计数表?

问题描述

假设我在 csv 文件中有以下数据example.csv

Word    Score
Dog     1
Bird    2
Cat     3
Dog     2
Dog     3
Dog     1
Bird    3
Cat     1
Bird    1
Cat     3

我想计算每个分数的每个单词的频率。预期的输出如下:

        1   2   3
Dog     2   1   1
Bird    0   1   1
Cat     1   0   2

我的代码如下:

将熊猫导入为 pd

x1 = pd.read_csv(r'path\to\example.csv')

def getUniqueWords(allWords) :
    uniqueWords = [] 
    for i in allWords:
        if not i in uniqueWords:
            uniqueWords.append(i)
    return uniqueWords

unique_words = getUniqueWords(x1['Word'])
unique_scores = getUniqueWords(x1['Score'])

scores_matrix = [[0 for x in range(len(unique_words))] for x in range(len(unique_scores)+1)]   
# The '+1' is because Python indexing starts from 0; so if a score of 0 is present in the data, the 0 index will be used for that. 

for i in range(len(unique_words)):
    temp = x1[x1['Word']==unique_words[i]]
    for j, word in temp.iterrows():
        scores_matrix[i][j] += 1  # Supposed to store the count for word i with score j

但这会产生以下错误:

IndexError                                Traceback (most recent call last)
<ipython-input-123-141ab9cd7847> in <module>()
     19     temp = x1[x1['Word']==unique_words[i]]
     20     for j, word in temp.iterrows():
---> 21         scores_matrix[i][j] += 1

IndexError: list index out of range

此外,即使我可以修复此错误,scores_matrix也不会显示标题(Dog, BirdCat作为行索引,和1, 23作为列索引)。我希望能够通过每个分数访问每个单词的计数 - 达到这个效果:

scores_matrix['Dog'][1]
>>> 2

scores_matrix['Cat'][2]
>>> 0

那么,我将如何解决/解决这两个问题?

标签: pythonpandasindexingword-frequencyfrequency-distribution

解决方案


groupby与 sort=False 和value_countsorsize一起使用unstack

df1 = df.groupby('Word', sort=False)['Score'].value_counts().unstack(fill_value=0)

df1 = df.groupby(['Word','Score'], sort=False).size().unstack(fill_value=0)

print (df1)
Score  1  2  3
Word          
Dog    2  1  1
Bird   1  1  1
Cat    1  0  2

如果顺序不重要,请使用crosstab

df1 = pd.crosstab(df['Word'], df['Score'])
print (df1)
Score  1  2  3
Word          
Bird   1  1  1
Cat    1  0  2
Dog    2  1  1

Last select by labels with DataFrame.loc:

print (df.loc['Cat', 2])
0

推荐阅读