【问题标题】:Problem with grouping and counting in pythonpython中的分组和计数问题
【发布时间】:2021-12-24 07:36:18
【问题描述】:

我一直在解决 python 中的一个问题,我有一个 3 列和超过一百万行的矩阵。第一列代表原产国,第二列代表目的地国家,第三列代表日期。例如:

US AU 02/03/2020
US CN 03/04/2020
US MX 03/04/2020
AU US 02/03/2020
AU AU 02/03/2020
AU CN 03/04/2020
AU MX 03/04/2020
AU US 02/03/2020
US AU 02/03/2020
US CN 03/04/2020
US MX 03/04/2020
AU US 02/03/2020

我想计算给定日期两个国家之间的所有航班。例如,02/03/2020 上从 USAU 的所有航班。我已经用 3 个 for 和一些 if 完成了它,但它已经运行了一个多星期,还没有完成。我想知道是否有人对我如何以更有效的方式处理此问题提出建议。

谢谢

【问题讨论】:

  • 你能告诉我们你的代码吗?
  • 使用 pandas 及其内置的过滤和计数方法。
  • 欢迎您!请阅读How to Ask。每当有问题询问代码时,问题都应包含该代码。否则,无法知道代码失败的原因。 minimal reproducible example 是另一篇值得阅读的好文章。
  • 为什么需要 3 个 for ? sum(flight['from'] == 'US' and flight['to'] == 'AU' and flight['date'] == '02/03/2020' for flight in list_of_flights)

标签: python grouping counting


【解决方案1】:

使用 pandas,它建立在 numpy 之上,因此您将从 C-speed 中受益。

假设这个文件作为输入:

文件.csv

US AU 02/03/2020
US CN 03/04/2020
US MX 03/04/2020
AU US 02/03/2020
AU AU 02/03/2020
AU CN 03/04/2020
AU MX 03/04/2020
AU US 02/03/2020
US AU 02/03/2020
US CN 03/04/2020
US MX 03/04/2020
AU US 02/03/2020
import pandas as pd
import io

df = pd.read_csv('file.csv', sep='\s', names=['from', 'to', 'date'])
df['date'] = pd.to_datetime(df['date'])
df.groupby(['from', 'to', 'date'], as_index=False).size()

输出:

  from  to       date  size
0   AU  AU 2020-02-03     1
1   AU  CN 2020-03-04     1
2   AU  MX 2020-03-04     1
3   AU  US 2020-02-03     3
4   US  AU 2020-02-03     2
5   US  CN 2020-03-04     2
6   US  MX 2020-03-04     2

340 万行的计时

注意。测试样本是通过连接 200k 次示例数据集生成的

320 ms ± 5.11 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

【讨论】:

    【解决方案2】:

    另一个使用 Pandas 的脚本

    !pip install Pandas
    import pandas as pd
    Fligts_df = pd.read_fwf("flights.txt",names=["FROM", "TO", "DATE"])
    Fligts_df.groupby(["FROM", "TO","DATE"])["DATE"].count()
    

    【讨论】:

      【解决方案3】:

      您可以在没有任何外部包(例如 pandas)的情况下轻松完成此操作,只需使用字典存储每一行​​的计数(即源、目标、日期的每个唯一组合)。标准defaultdict在这种情况下非常方便:

      import collections
      
      flights = collections.defaultdict(int)
      with open('file.csv', 'rt') as file:
          for line in file:
              flights[line.strip()] += 1
      print(flights['AU US 02/03/2020'])  # prints 3
      

      在包含 100 万个随机生成的“航班”的文件上运行此代码大约需要一秒钟。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-01-28
        • 1970-01-01
        • 1970-01-01
        • 2013-05-09
        • 1970-01-01
        相关资源
        最近更新 更多