2

我有两个代表来自两个不同年份的数据的 CSV 文件。我知道如何使用 csvwriter 和 dictkeys 进行基本的合并,但问题出在此处:虽然 CSV 大多共享列标题,但每个列可能都有唯一的列。如果一个物种在一年内被捕获,而在另一年没有被捕获,则该列将仅在该年出现。如何将新数据合并到旧数据,创建新列并在这些列中用零填充旧数据?

文件 1: "Date","Time","Species A","Species B", "Species X"

文件 2: "Date","Time", "Species A", "Species B", "Species C"

我需要最终结果是一个带有此标头的 csv:"Date","Time","Species A","Species B", "Species C", "Species X"

4

3 回答 3

5

其他人可能会使用该csv模块发布解决方案,因此我将提供一个pandas解决方案以供比较:

import pandas as pd

df1 = pd.read_csv("fish1.csv")
df2 = pd.read_csv("fish2.csv")

df = pd.concat([df1, df2]).fillna(0)
df = df[["Date", "Time"] + list(df.columns[1:-1])]
df.to_csv("merged_fish.csv", index=False)

解释:

首先,我们读入两个文件:

>>> df1 = pd.read_csv("fish1.csv")
>>> df2 = pd.read_csv("fish2.csv")
>>> df1
   Date  Time  Species A  Species B  Species X
0     1     2          3          4          5
1     6     7          8          9         10
2    11    12         13         14         15
>>> df2
   Date  Time  Species A  Species B  Species C
0    16    17         18         19         20
1    21    22         23         24         25
2    26    27         28         29         30

然后我们简单地将它们连接起来,它会自动用以下内容填充缺失的数据NaN

>>> df = pd.concat([df1, df2])
>>> df
   Date  Species A  Species B  Species C  Species X  Time
0     1          3          4        NaN          5     2
1     6          8          9        NaN         10     7
2    11         13         14        NaN         15    12
0    16         18         19         20        NaN    17
1    21         23         24         25        NaN    22
2    26         28         29         30        NaN    27

你希望它们用 0 填充,所以:

>>> df = pd.concat([df1, df2]).fillna(0)
>>> df
   Date  Species A  Species B  Species C  Species X  Time
0     1          3          4          0          5     2
1     6          8          9          0         10     7
2    11         13         14          0         15    12
0    16         18         19         20          0    17
1    21         23         24         25          0    22
2    26         28         29         30          0    27

但是,这个订单并不是您想要的,而且是您想要TimeDate第一个,所以:

>>> df = df[["Date", "Time"] + list(df.columns[1:-1])]
>>> df
   Date  Time  Species A  Species B  Species C  Species X
0     1     2          3          4          0          5
1     6     7          8          9          0         10
2    11    12         13         14          0         15
0    16    17         18         19         20          0
1    21    22         23         24         25          0
2    26    27         28         29         30          0

然后我们将其保存为 CSV 文件:

>>> df.to_csv("merged_fish.csv", index=False)

生产

Date,Time,Species A,Species B,Species C,Species X
1,2,3,4,0.0,5.0
6,7,8,9,0.0,10.0
11,12,13,14,0.0,15.0
16,17,18,19,20.0,0.0
21,22,23,24,25.0,0.0
26,27,28,29,30.0,0.0
于 2013-04-15T14:36:58.850 回答
1

这是csvPython 3 中的模块解决方案:

import csv

# Generate some data...

csv1 = '''\
Date,Time,Species A,Species B,Species C
04/01/2012,13:00,1,2,3
04/02/2012,13:00,1,2,3
04/03/2012,13:00,1,2,3
04/04/2012,13:00,1,2,3
'''

csv2 = '''\
Date,Time,Species A,Species B,Species X
04/01/2013,13:00,1,2,3
04/02/2013,13:00,1,2,3
04/03/2013,13:00,1,2,3
04/04/2013,13:00,1,2,3
'''

with open('2012.csv','w') as f:
    f.write(csv1)
with open('2013.csv','w') as f:
    f.write(csv2)

# The actual program

years = ['2012.csv','2013.csv']

lines = []
headers = set()
for year in years:
    with open(year,'r',newline='') as f:
        r = csv.DictReader(f)
        lines.extend(list(r))                 # Merge lines from all files.
        headers = headers.union(r.fieldnames) # Collect unique column names.

# Sort the unique headers keeping Date,Time columns first.
new_headers = ['Date','Time'] + sorted(headers - set(['Date','Time']))

with open('result.csv','w',newline='') as f:
    # The 3rd parameter is the default if the key isn't present.
    w = csv.DictWriter(f,new_headers,0)
    w.writeheader()
    w.writerows(lines)

# View the result

with open('result.csv') as f:
    print(f.read())

输出:

Date,Time,Species A,Species B,Species C,Species X
04/01/2012,13:00,1,2,3,0
04/02/2012,13:00,1,2,3,0
04/03/2012,13:00,1,2,3,0
04/04/2012,13:00,1,2,3,0
04/01/2013,13:00,1,2,0,3
04/02/2013,13:00,1,2,0,3
04/03/2013,13:00,1,2,0,3
04/04/2013,13:00,1,2,0,3
于 2013-04-15T15:24:05.790 回答
0

根据文档,看起来您应该能够读出两个文件,合并两个提取字典中的键,然后使用编写器上的fieldnamesrestval参数来实现您的 0 默认值。

于 2013-04-15T14:06:38.200 回答