【问题标题】:Merce csv files (from a folder) into one, adding columns with different names using PythonMerce csv文件(来自文件夹)合二为一,使用Python添加具有不同名称的列
【发布时间】:2017-08-05 13:05:08
【问题描述】:

我需要将文件夹中的多个 CSV 文件合并为一个。

我原来的数据是这样的

y_1980.csv:

     country   y_1980
0        afg    196
1        ago    125
2        alb     23
3          .      .
.          .      .

y_1981.csv:

     country   y_1981
0        afg    192
1        ago    120
2        alb     0
3          .      .
.          .      .

y_20xx.csv:

     country   y_20xx
0        afg    176
1        ago    170
2        alb     76
3          .      .
.          .      .

我期望得到的是类似这样的东西:

     country   y_1980   y_1981   ...   y_20xx    
0        afg      196      192   ...      176
1        ago      125      120   ...      170
2        alb       23        0   ...       76
3          .        .        .   ...        .
.          .        .        .   ...        .

到目前为止,我当前的代码如下,但我得到的结果是数据框在前一个之后合并:

interesting_files = glob.glob("/Users/Desktop/Data/*.csv") 

header_saved = True

with open('/Users/Desktop/Data/table.csv','wb') as fout:
    for filename in interesting_files:

        with open(filename) as fin:
            header = next(fin)
            if not header_saved:
                fout.write(header)
                header_saved = True
            for line in fin:
                fout.write(line)

【问题讨论】:

  • 如果您使用pandas,它会容易得多。因为它摆脱了for-loop 并保持低内存占用。此外,它更全面。如果您需要 pandas 解决方案,请告诉我。
  • 是的,我想要一个熊猫解决方案
  • 检查答案。它将优雅地工作并且更全面。让我知道它是否有效。
  • 如果有帮助,请接受并支持答案。谢谢。

标签: python csv pandas merge


【解决方案1】:

Pandas 让这一切变得非常简单。使用循环和合并,您可以简单地执行以下操作:

代码:

import pandas as pd

files = ['file1', 'file2']
dfs = None
for filename in files:
    df = pd.read_csv(filename, sep='\s+')
    if dfs is None:
        dfs = df
    else:
        dfs = dfs.merge(df, how='outer')
    print(df)
print(dfs)
dfs.to_csv('file3', sep=' ')

结果:

  country  y_1980
0     afg     196
1     ago     125
2     alb      23

  country  y_1981
0     afg     192
1     ago     120
2     alb       0

  country  y_1980  y_1981
0     afg     196     192
1     ago     125     120
2     alb      23       0

【讨论】:

    【解决方案2】:

    如果你使用 pandas 会容易得多。原因是它将摆脱for-loop 问题并保持memory footprint 低。

    import pandas as pd
    
    # read the files first
    
    y_1980 = pd.read_csv('y_1980.csv', sep='\t')
    y_1981 = pd.read_csv('y_1981.csv', sep='\t')
    

    如果值用逗号分隔,则可以更改 sep 选项。

    # set 'country' as the index to use this value to merge.
    y_1980 = y_1980.set_index('country', append=True)
    y_1981 = y_1981.set_index('country', append=True)
    
    print(y_1980)
    print(y_1981)
    
                y_1980
        country        
      0 afg         196
      1 ago         125
      2 alb          23
    
    
                 y_1980
        country        
      0 afg         192
      1 ago         120
      2 alb           0
    
    # set the frames to merge. You can add as many dataframe as you want.
    frames =[y_1980, y_1981]
    
    # now merge the dataframe
    merged_df = pd.concat(frames, axis=1).reset_index(level=['country'])
    print(result)
    
          country  y_1980  y_1980
    0     afg     196     192
    1     ago     125     120
    2     alb      23       0
    

    附加说明:如果您只想合并所有帧中存在的键,您可以添加选项:how='inner' and drop=na。如果要合并所有帧中的所有可能数据,请使用how='outer'

    查看此链接了解更多详情:http://pandas.pydata.org/pandas-docs/stable/merging.html

    【讨论】:

      【解决方案3】:

      代码的运行顺序看起来像:

      • 打开文件 #1
      • 如果没有保存就写标题
      • 写入数据行
      • 打开文件 #2
      • ...等

      将所有数据连接到一个文件中。听起来您实际上想通过“国家/地区”列加入

      import glob
      import pandas as pd
      csvs = glob.glob("*.csv")
      dfs = []
      
      for csv in csvs:
        dfs.append(pd.read_csv(csv))
      
      merged_df = dfs[0]
      
      for df in dfs[1:]:
        merged_df = pd.merge(merged_df,df,on=['country'])
      
      
      merged_df.to_csv('out.csv',index=False)
      

      【讨论】:

      • 我正在尝试运行此代码,但出现此错误:---> 13 merge_df = for df in dfs[1:]: IndexError: list index out of range跨度>
      • 修改了我的代码以修复一些格式,但你能检查以确保 dfs 确实包含读入的数据帧列表吗?带有dfs[1:] 的 for 循环遍历除第一个数据帧以外的所有数据帧,因为它是在声明 merged_df 时分配的
      猜你喜欢
      • 1970-01-01
      • 2013-10-10
      • 2023-02-05
      • 1970-01-01
      • 2014-03-21
      • 2019-08-28
      • 2019-04-03
      • 1970-01-01
      • 2018-08-31
      相关资源
      最近更新 更多