【问题标题】:how read csv, append new data, and write to a new csv with pandas如何使用 pandas 读取 csv、追加新数据和写入新 csv
【发布时间】:2018-07-11 02:05:56
【问题描述】:

我以前没有使用过 Pandas,看来我需要一些初步帮助。我在任何地方都找不到这个具体的例子。

我有一个 csv 文件,比如 file1.csv 如下:

ID     value1     value2
1       100        200
2       101        201

我需要从 file1.csv 一次读取 1 行,附加 2 个新列 info/data,然后将所有内容写入一个名为 file2.csv 的新文件。 file2.csv 应该如下所示:

ID     value1     value2     value3     value4
1       100        200        10         20
2       101        201        11         21

谁能指导或给出一个简短的例子来说明如何做到这一点(读取 file1,附加新数据(value3 和 value4 列),并将其写入 file2)?

附录: 我需要从file1一次读取1行,一次将1行写入file2。

【问题讨论】:

  • pandas 有非常好的阅读各种格式的工具。见pandas.read_csv。同样,您可以使用 DataFrame.to_csv 将 DataFrame 保存到 csv
  • 如果您打算一次阅读一行,我认为 pandas 不适合您(因此可能会出现一些减速)。一个简单的with open('file.csv') as f: ... 就足够了
  • @Arda Arslan,感谢您的补充评论。性能不是我的具体情况的问题,而是记忆的问题。Pandas 也是我想要使用更多的东西,所以这对我来说是很好的锻炼。

标签: python pandas csv dataframe


【解决方案1】:

以下内容将加载file1.csv,添加'value3''value4' 列,并将结果数据帧输出为csv。

import pandas as pd

df = pd.read_csv('file1.csv')
df['value3'] = [10, 11]
df['value4'] = [20, 21]
df.to_csv('file2.csv')

file1.csv的内容:

ID,value1,value2
1,100,200
2,101,201

file2.csv的内容:

,ID,value1,value2,value3,value4
0,1,100,200,10,20
1,2,101,201,11,21

【讨论】:

  • 这太棒了!但我需要一次读取 1 行,然后需要一次写入 1 行到 file2。我错过了上面提到它是我的错误。如果我没看错,您的代码会一次读取/写入整个文件。如何一次读取和写入 1 行?
  • @edn,但是为什么你需要一次做一行? pandas 的主要功能在于它允许您摆脱一次只做一行的操作,而是可以对整个 DataFrame 执行矢量化操作
  • 我同意@ALollz 我想我不明白你为什么特别想一次读一行
  • 我明白你的意思。因为我会将 file1 中的数据用于其他目的。上面的 value3 和 value4 列将是该处理的结果。 file1 是一个大文件,我无法一次处理所有内容。这就是为什么...我实际上也可以处理 5 或 10 行,但如果我看到如何一次处理 1 行,我相信它会以后更容易配置它。
  • 至少,您应该能够在内存中容纳不止一行。至少你可以处理大块的文件,一次可能有几千块。
【解决方案2】:

使用read_csvto_csv。使用to_csv 中的index 关键字arg 来保留或删除索引。

In [117]: df = pd.read_csv('eg.csv')

In [118]: df
Out[118]:
   col 1  col 2  col 3
0      4      5      6
1      7      8      9

In [119]: df['new col'] = 'data'

In [120]: df
Out[120]:
   col 1  col 2  col 3 new col
0      4      5      6    data
1      7      8      9    data

In [121]: df.to_csv('eg.new.csv')

In [122]: new_df = pd.read_csv('eg.new.csv')      # includes the index

In [123]: new_df
Out[123]:
   Unnamed: 0  col 1  col 2  col 3 new col
0           0      4      5      6    data
1           1      7      8      9    data

In [124]: df.to_csv('eg.new.csv', index=False)    # excludes index

In [125]: new_df = pd.read_csv('eg.new.csv')

In [126]: new_df
Out[126]:
   col 1  col 2  col 3 new col
0      4      5      6    data
1      7      8      9    data

【讨论】:

    【解决方案3】:

    虽然通常有更好的解决方案,例如使用Dask、更改dtypes 或使用分类变量,但一种替代方法是简单地以块的形式处理文件。

    import pandas as pd
    
    # Read one line at at time. Change chunksize to process more lines at a time. 
    reader = pd.read_csv('test.csv', chunksize=1)
    write_header = True  # Needed to get header for first chunk
    
    for chunk in reader:
        # Do some stuff
        chunk['val3'] = chunk.val1**2
        chunk['val4'] = chunk.val2*4
    
        # Save the file to a csv, appending each new chunk you process. mode='a' means append.
        chunk.to_csv('final.csv', mode='a', header=write_header, index=False)
        write_header = False  # Update so later chunks don't write header
    

    样本数据:test.csv

    val1,val2
    1,2
    3,4
    5,6
    7,8
    9,10
    11,12
    13,14
    15,16
    

    输出:final.csv

    val1,val2,val3,val4
    1,2,1,8
    3,4,9,16
    5,6,25,24
    7,8,49,32
    9,10,81,40
    11,12,121,48
    13,14,169,56
    15,16,225,64
    

    【讨论】:

    • 看似我们同时提交了类似的答案,但你的更优雅,它提供了一个代码更少的解决方案。谢谢!解决了!
    【解决方案4】:

    看起来下面的代码 sn-p 正在解决我的问题。感谢@aydow 和@Arda Arslan 给予的启发。

    下面这段代码只用头文件名创建了file2,其余的都是空的。

    column_names = ['ID', 'value1', 'value2', 'value3', 'value4']
    raw_data = {column_names[0]: [], 
                column_names[1]: [],
                column_names[2]: [],
                column_names[3]: [], 
                column_names[4]: []}
    df = pd.DataFrame(raw_data, columns = column_names)
    df.to_csv("file2.csv", index=False) 
    

    下面的代码每次从 file1 读取 1 行并将其附加到 file2。

    for df in pd.read_csv('file1.csv', chunksize=1):
        df['value3'] = 11
        df['value4'] = 22
        df.to_csv("file2.csv", header=False, index=False, mode='a')
    

    更改参数 chunksize 的值有助于更改您一次要读取/写入的 # 行。 如果您认为可以更优雅地完成,我们非常欢迎您的改进。

    【讨论】:

      猜你喜欢
      • 2020-06-22
      • 2018-08-04
      • 2014-11-23
      • 2019-04-11
      • 2022-01-05
      • 2021-03-13
      • 1970-01-01
      • 2019-12-15
      • 2022-01-26
      相关资源
      最近更新 更多