【问题标题】:Python - same kind of data, same code, but different outcomesPython - 相同类型的数据,相同的代码,但不同的结果
【发布时间】:2020-12-15 20:34:03
【问题描述】:

如果我弄错了,我提前道歉,但下面显示的代码和数据在我看来相同,但会产生不同的结果。 我的数据如下:

csv 文件

1907-09-01,108,13.5,7.9,20.7
1907-09-02,108,16.2,7.9,22
1907-09-03,108,16.2,13.1,21.3
1907-10-04,108,16.5,11.2,22
1907-10-05,108,17.6,10.9,25.4
1907-10-06,108,13,11.2,21.3
1907-11-07,108,11.3,6.3,16.1
1907-11-08,108,8.9,3.9,14.9
1907-11-09,108,11.6,3.8,21.1
1907-11-10,108,14.2,6.4,24.1
1907-11-11,108,15.4,10.1,20.4
1907-12-12,108,13.9,11.1,17.4
1907-12-13,108,13.8,8.3,21.3
1907-12-14,108,13,6.1,20.6
1907-12-15,108,13.1,5.7,20.9

代码

f = open('ta_20200826183704.csv', 'r')
data = csv.reader(f)
header = next(data)

for row in data:
    print(row)


['1907-10-01', '108', '13.5', '7.9', '20.7']
['1907-10-02', '108', '16.2', '7.9', '22']
['1907-10-03', '108', '16.2', '13.1', '21.3']
['1907-10-04', '108', '16.5', '11.2', '22']
......

该数据集包含大约 40,000 天的数据点。使用此数据集,我尝试获取最后一列中的数据点(一天中的最高温度)并根据一天中的月份将它们放入列表中的列表中(例如,放入 all_month = [[], [], [], [], [], [], [], [], [], [], [], []] 中的相应列表中就像所有一月份的数据点都进入第一个嵌套列表)。简单来说,我尝试手动做groupby('month') of pandas

当我运行下面的代码时:

import csv

f = open('ta_20200826183704.csv', 'r')
data = csv.reader(f)
header = next(data)

all_month = []
month = []

for i in range(1,13):
    all_month.append(month)
    
for row in data:
    month = int(row[0].split('-')[1])
    for i in range(1,13):
        if month == i:
            all_month[i-1].append(row[-1])

输出在每个嵌套列表中都有相同的数据,这意味着最后一列中的数据点没有按月份分组(即,所有这些点都放入每个嵌套列表中)。

真正让我困惑的是,当我手动输入相同数据的一小部分时,我能够得到预期的结果:

test_list = [[],[],[],[],[],[],[],[],[],[],[],[]]
test_data = [['1907-09-01', '108', '13.5', '7.9', '20.7'],
['1907-09-02', '108', '16.2', '7.9', '22'],
['1907-09-03', '108', '16.2', '13.1', '21.3'],
['1907-10-04', '108', '16.5', '11.2', '22'],
['1907-10-05', '108', '17.6', '10.9', '25.4'],
['1907-10-06', '108', '13', '11.2', '21.3'],
['1907-11-07', '108', '11.3', '6.3', '16.1'],
['1907-11-08', '108', '8.9', '3.9', '14.9'],
['1907-11-09', '108', '11.6', '3.8', '21.1'],
['1907-11-10', '108', '14.2', '6.4', '24.1'],
['1907-11-11', '108', '15.4', '10.1', '20.4'],
['1907-12-12', '108', '13.9', '11.1', '17.4'],
['1907-12-13', '108', '13.8', '8.3', '21.3'],
['1907-12-14', '108', '13', '6.1', '20.6'],
['1907-12-15', '108', '13.1', '5.7', '20.9']]

for row in test_data:
    month = int(row[0].split('-')[1])
    for i in range(1,13):
        if month == i:
            test_list[i-1].append(row[-1])

输出是:

[[],
 [],
 [],
 [],
 [],
 [],
 [],
 [],
 ['20.7', '22', '21.3'],
 ['22', '25.4', '21.3'],
 ['16.1', '14.9', '21.1', '24.1', '20.4'],
 ['17.4', '21.3', '20.6', '20.9']]

我能注意到两个代码之间的唯一区别是数据的输入(或读取)方式。

如果有人能指出我做错了什么和/或为什么会产生不同的结果,我将不胜感激。

【问题讨论】:

    标签: python csv for-loop


    【解决方案1】:

    让我们看看这个代码块:

    all_month = []
    month = []
    
    for i in range(1,13):
        all_month.append(month)
    

    这会将 1 个列表放入 all_month 十二次;您期望的是一个包含 12 个不同列表的列表,但这段代码所做的基本上是创建 12 个指向单个列表对象的指针。如果您使用这些指针中的任何一个,您正在修改或读取所有这些指针共有的列表,这就是您所看到的。您可以通过在all_month 的每个条目上调用id() 来看到这一点;您会看到它们都有相同的 id。

    这里有很多解决方案,如果您使用all_month.append([]),那么每次您追加到all_month 时,您都会插入一个新列表。

    【讨论】:

      【解决方案2】:

      我同意迈克尔的回答。但是为什么不直接使用 pandas 呢?

      import pandas as pd
          
      test_data = [['1907-09-01', '108', '13.5', '7.9', '20.7'],
      ['1907-09-02', '108', '16.2', '7.9', '22'],
      ['1907-09-03', '108', '16.2', '13.1', '21.3'],
      ['1907-10-04', '108', '16.5', '11.2', '22'],
      ['1907-10-05', '108', '17.6', '10.9', '25.4'],
      ['1907-10-06', '108', '13', '11.2', '21.3'],
      ['1907-11-07', '108', '11.3', '6.3', '16.1'],
      ['1907-11-08', '108', '8.9', '3.9', '14.9'],
      ['1907-11-09', '108', '11.6', '3.8', '21.1'],
      ['1907-11-10', '108', '14.2', '6.4', '24.1'],
      ['1907-11-11', '108', '15.4', '10.1', '20.4'],
      ['1907-12-12', '108', '13.9', '11.1', '17.4'],
      ['1907-12-13', '108', '13.8', '8.3', '21.3'],
      ['1907-12-14', '108', '13', '6.1', '20.6'],
      ['1907-12-15', '108', '13.1', '5.7', '20.9']]
      
      
      df = pd.DataFrame(test_data) 
      
      # You can load this directly from your csv like
      # df = pd.read_csv("filename.csv") 
      
      df[0] = pd.to_datetime(df[0])
      
      grouped_df = df.groupby(df[0].dt.strftime('%m'))[4].apply(list).sort_values()
      
      print(grouped_df)
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-11-08
        • 1970-01-01
        • 2022-08-05
        • 1970-01-01
        • 1970-01-01
        • 2015-10-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多