通过Python更改CSV文件中的特定值

时间:2012-06-14 13:00:07

标签: python csv filereader

我需要改变csv文件列的特定值的方法。例如,我有csv文件:

"Ip","Sites"
"127.0.0.1",10
"127.0.0.2",23
"127.0.0.3",50

我需要更改“127.0.0.2”的值23到30。

我使用csv库:import csv

感谢任何帮助,因为我是Python的新手。谢谢!

4 个答案:

答案 0 :(得分:30)

这是打开csv文件的解决方案,更改内存中的值,然后将更改写回磁盘。

r = csv.reader(open('/tmp/test.csv')) # Here your csv file
lines = list(r)

行内容:

[['Ip', 'Sites'],
 ['127.0.0.1', '10'],
 ['127.0.0.2', '23'],
 ['127.0.0.3', '50']]

修改值:

lines[2][1] = '30'

行内容:

[['Ip', 'Sites'],
 ['127.0.0.1', '10'],
 ['127.0.0.2', '30'],
 ['127.0.0.3', '50']]

现在我们只需将其写回文件

writer = csv.writer(open('/tmp/output.csv', 'w'))
writer.writerows(lines)

答案 1 :(得分:13)

您无法真正替换现有文件中的值。相反,你需要:

  1. 读入现有文件
  2. 在内存中更改文件
  3. 写出新文件(覆盖现有文件)
  4. 您还可以做的是逐行读取现有文件,将其写入新文件,同时立即替换值。完成后,关闭两个文件,删除原始文件并重命名新文件。

答案 2 :(得分:10)

您可以使用非常强大的名为pandas的库。这是一个例子。

import pandas as pd
df = pd.read_csv("test.csv")
df.head(3) #prints 3 heading rows

输出:

    Ip  Sites
0   127.0.0.1   10
1   127.0.0.2   23
2   127.0.0.3   50

现在,如果您想更改'网站'第一行中的列,运行:

df.set_value(1, "Sites", 30)

如果你想改变所有价值,那么' Ip'等于127.0.0.2,运行:

df.loc[df["Ip"]=="127.0.0.2", "Sites"] = 30

最后,保存值:

df.to_csv("test.csv", index=False)

答案 3 :(得分:3)

accepted answer的替代方法是:

  • fileinputinplace=True一起使用就地修改文件
  • 使用csv.DictReader通过标题而不是索引来访问列
    • 这仅在CSV具有标题的情况下有效

测试CSV:

Ip,Sites
127.0.0.1,10
127.0.0.2,23
127.0.0.3,50

测试代码:

import fileinput

with fileinput.input(files=('test.csv'), inplace=True, mode='r') as f:
    reader = csv.DictReader(f)
    print(",".join(reader.fieldnames))  # print back the headers
    for row in reader:
        if row["Ip"] == "127.0.0.2":
            row["Sites"] = "30"
        print(",".join([row["Ip"], row["Sites"]]))

主要区别在于您不必手动打开输入文件并创建输出文件,因为inplace=True已经在后台进行了操作:

可选的就地过滤:如果关键字参数inplace=True为 传递给fileinput.input()FileInput构造函数的文件 被移到备份文件,标准输出定向到输入 文件(如果已经存在与备份文件同名的文件, 将被无提示替换)。这样就可以编写过滤器 会在适当位置重写其输入文件。

循环逐行遍历CSV(标题行除外),因此您可以对每一行进行所需的任何处理。

如果您仍想保留原始文档,则可以传入backup=".backup",以便fileinput创建一个 test.csv.backup 文件。

此外,请注意,在就地编辑中,“ 标准输出定向到输入文件”,因此print(..)将其输出到文件中而不是命令行中。如果要实际打印到控制台,则需要像stderr中那样指定print(..., file=sys.stderr)