【问题标题】:Counting number of occurrences of each value in an excel column [closed]计算excel列中每个值的出现次数[关闭]
【发布时间】:2018-03-20 23:53:03
【问题描述】:

我有一个大的 excel 文件,其中 A 列的每个单元格中都有随机数,用于该 excel 表中的所有 100 万多行。我正在尝试在 B 列中打印每个值的出现次数。通常,我在 Excel 本身中执行此操作,首先对数据进行排序,然后使用 COUNTIF 公式。但由于我有这么多行(100 万行),因此在 B 列的所有行中复制粘贴公式似乎不起作用。 Excel 需要永远计算并且经常挂断。我现在想尝试用 Python 来做这件事。

非常感谢任何让我入门的想法!

更新: 这是我尝试过的:

import csv
import collections
with open ('test.csv','rb') as f:
    reader = csv.reader(f)
    my_list = list(reader)

#print my_list[1000]
counter = collections.Counter(my_list)
print counter

但我得到 TypeError: unhashable type: 'list'

谁能帮忙?

【问题讨论】:

  • 我会将其转换为 csv,然后使用库 csv 对其进行解析,提取列(例如使用列表理解),然后使用集合中的 Counter
  • 还有Python库可以直接读取Excel文件。熊猫可能很适合stackoverflow.com/questions/3239207/…
  • 那么你有一个csv文本文件还是一个excel文件?
  • 另外,请修正你的缩进。

标签: python excel


【解决方案1】:

考虑使用pandas,它易于使用并针对大型数据集进行了优化。

给定

import csv
import random

import pandas as pd

为了演示,这里是一个带有单列随机数的 csv 文件:

random.seed(123)
data = [random.randint(0, 100) for _ in range(25)]

# Write data to csv
filename = "discard.csv"
with open(filename, "w+") as f:
    writer = csv.writer(f)
    for row in data:
        writer.writerow([str(row)])

代码

# Read and count
s = pd.read_csv(filename, header=None, index_col=False)[0]
s.value_counts()

输出

34    2
20    2
6     2
71    2
43    2
42    2
98    1
11    1
99    1
4     1
13    1
31    1
48    1
17    1
52    1
55    1
68    1
89    1
0     1
Name: 0, dtype: int64

将后面的代码应用到您的数据集。

【讨论】:

    【解决方案2】:

    首先一点建议:您的问题内容正确,但措辞很差。我之所以回答是因为前者,但我觉得有必要指出后者,这样你就可以避免将来获得如此多的接近投票。 “任何让我开始的想法都将非常感激!”和“谁能帮忙?”不是 SO 的有效问题。这里的问题是它们是绒毛,有损于真正的问题,以至于大多数评论者会将它们视为触发短语。在你的情况下,你实际上有一个很好的清晰的问题陈述,一个几乎准确的编码尝试,你所需要的只是针对特定异常的帮助。下次,将您的问题表述为关于您的错误或实际问题,并避免像“您能帮忙吗?”这样的含糊不清。

    够了。

    CSV 阅读器是对 CSV 行的迭代。每一行都是一个列表。因此,当您执行list(reader) 时,您实际上是在创建一个列表列表。在您的情况下,每个列表仅包含一个元素,但这与 Counter 无关:列表不能是字典键,因此您会遇到例外。从字面上看,您需要更改的只是在将每行的第一个元素传递给Counter 之前提取它。将my_list = list(reader) 替换为以下任意一种:

    my_list = list(r[0] for r in reader)
    

    my_list = [r[0] for r in reader]
    

    counter = collections.Counter(r[0] for r in reader)
    

    最后一个创建了一个生成器表达式,该表达式将被延迟计算。对于非常大的输入,这可能是您的最佳选择,因为它不会将整个数据集保留在内存中,只会保留直方图。

    由于生成器的评估是惰性的,因此您无法评估 with 块之外的 Counter。如果您尝试这样做,文件将已经关闭,并且生成器将在第一次迭代时引发错误。

    在上述任何表达式中使用 operator.itemgetter 而不是显式的 r[0] 可能会略微提高速度。综合起来,下面的例子非常接近你已经拥有的:

    import csv
    from collections import Counter
    from operator import itemgetter
    
    with open ('test.csv','rb') as f:
        reader = csv.reader(f)
        g = itemgetter(0)
        counter = Counter(g(r) for r in reader)
    print(counter)
    

    【讨论】:

      【解决方案3】:

      您可以在 Python 中使用相同的策略:将整个数字序列读入一个列表,对列表进行排序并计算重复的数量。

      【讨论】:

      • 对于选项数量相对较少的情况似乎有点过分了。直方图应该是 O(n) 操作,而不是 O(nlogn)
      • 这个评论的答案似乎也有点过头了。
      【解决方案4】:

      pandas 包是一种加载 Excel 数据的简单方法。然后您可以使用结果数据帧的value_counts() 成员函数。例如,

      import pandas as pd
      xl = pd.ExcelFile("C:\\Temp\\test.xlsx") # or whatever your filename is
      df = xl.parse("Sheet1", header=None)
      answer = df[0].value_counts()
      print(answer)
      

      【讨论】:

      • 考虑到数百万行的部分,最好不要调用额外的开销。 OP 建议的解决方案比使用 pandas 更轻量。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-07-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多