【问题标题】:Creating new arrays based on unique keys and condition in Python根据 Python 中的唯一键和条件创建新数组
【发布时间】:2018-09-17 21:38:17
【问题描述】:

我打算用 Python 而不是 Excel 来计算大量数据,但我被困住了,因为我知道 Excel 命令,而且我很难在 Python 中复制它。

基本上,我想导入 CSV 文件,确定 C 列的位置,然后对于 A 列中的所有唯一值,将 C 中适用于 B 中条件 1990 < x < 2000 的所有值相加

A,B,C
9,1952,125
2,1994,69
3,1973,72
5,1992,85
1,1994,38
1,1994,95
4,1992,29
8,1984,94

我开始:

import csv
with open('TestCase.txt', 'rb') as csvfile:
    reader = csv.reader(csvfile, delimiter=',')
    row1 = next(reader)

我不想编写多个 if 语句,而是创建由 0 和 1 组成的新数组,然后将 C 中的所有值相加。

给定另一个条件,结果将如下所示

1980<x<1989 94
1990<x<2000 316

额外奖励是 A 中唯一值的总数,代表总和

UniqueValues    Condition   TotalSum
1   1980<x<1989 94
4   1990<x<2000 316

【问题讨论】:

  • 你的输出期望是什么?我可以帮你。
  • 应该归档唯一值吗?
  • @mehrdad-pedramfar 最后,我想看看 C 中的值的总和,它适用于 B 提到的条件。下一步是添加另一个条件,例如1980
  • @ThomasJunk 否。总和必须包含所有值。
  • @energyMax 我发布了一个答案,它返回一个字典。你还需要什么别的吗 ?告诉我我会更新我的答案。

标签: python excel indexing match


【解决方案1】:

你可以用这个:

l = list()
d = dict()
with open('TestCase.txt', 'r') as file:
    for line in file:
        l.append(line.rstrip("\n").split(',')) # l=[[9,1952,125],[2,1994,69],...]

    for item in l:
        if 1990 < int(item[1]) < 2000: # The desired condition for colum B 
            d[item[0]] = d[item[0]] + int(item[2]) if item[0] in d else int(item[2])

d 字典将以 A 的唯一值作为其键,并将 C 的总和作为其值。

【讨论】:

    【解决方案2】:

    如果您对使用第 3 方库感到满意,可以通过 pandas 进行矢量化:

    import pandas as pd
    
    # read csv file
    df = pd.read_csv('file.csv')
    
    # filter column B, group by A, sum C
    res = df.loc[df['B'].between(1990, 2000)]\
            .groupby('A')['C'].sum()\
            .reset_index()
    

    结果:

       A    C
    0  1  133
    1  2   69
    2  4   29
    3  5   85
    

    【讨论】:

      【解决方案3】:
      from io import StringIO
      import pandas as pd
      
      txt = StringIO("""
      A,B,C
      9,1952,125
      2,1994,69
      3,1973,72
      5,1992,85
      1,1994,38
      1,1994,95
      4,1992,29
      8,1984,94
      """)
      
      df = pd.read_csv(txt )
      
      #condition = (df["B"] >1980) & (df["B"] < 1989)
      condition = (df["B"] >1990) & (df["B"] < 2000)
      df_cond = df[condition]
      
      df_uniq = df_cond.drop_duplicates('A', keep=False)
      df_uniq_keep_first = df_cond.drop_duplicates('A', keep="first")
      df_uniq_keep_last = df_cond.drop_duplicates('A', keep="last")
      
      sum_dupl = df_cond["C"].sum()
      sum_uniq = df_uniq["C"].sum()
      sum_uniq_keep_first = df_uniq_keep_first["C"].sum()
      sum_uniq_keep_last = df_uniq_keep_last["C"].sum()
      
      print("sum with duplicates  : " + str(sum_dupl))            #316
      print("sum pure unique      : " + str(sum_uniq))            #183
      print("sum unique keep first: " + str(sum_uniq_keep_first)) #221 
      print("sum unique keep last : " + str(sum_uniq_keep_last))  #278
      

      【讨论】:

      • 这可行,但是对于条件 1990
      • 谢谢。如果我导入 txt,这将如何工作?我应该使用 import CSV 并在其上使用 StringIO 函数吗?
      • filename = "file_to_import.csv" df = pd.read_csv(filename ) 我使用 StringIO 只是为了将文本变量“转换”为演示代码的文件。即你不需要 from io import StringIO
      • 谢谢。它就像魅力一样。在这种情况下,命令“df_cond.drop_duplicates”有什么作用?
      • 我试图满足您的要求“考虑到所有值” - 所以没有唯一性。我刚刚编辑了演示代码,了解如何处理重复项 {False, "first", "last"} 的各种方法。如您所见,对于条件 = (df["B"] >1990) & (df["B"]
      猜你喜欢
      • 2011-02-15
      • 2016-12-20
      • 2021-02-21
      • 2021-12-08
      • 2011-04-06
      • 2018-08-08
      • 2017-01-17
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多