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

通过Python更改CSV文件中的特定值,python,csv,Python,Csv,我需要一种方法来更改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库:导入csv您不能真正替换现有文件中的值。相反,您需要: 读取现有文件 更改内存中的文件 写出新文件(覆盖现有文件) 您还可以逐行读取现有文件,将其写入新文件,同时动态替换值。完成后,关闭两个文件,删除原始文件并重命名新文件。这是打开csv文件,

我需要一种方法来更改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库:
导入csv

您不能真正替换现有文件中的值。相反,您需要:

  • 读取现有文件
  • 更改内存中的文件
  • 写出新文件(覆盖现有文件)

  • 您还可以逐行读取现有文件,将其写入新文件,同时动态替换值。完成后,关闭两个文件,删除原始文件并重命名新文件。

    这是打开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']]
    
    [['Ip', 'Sites'],
     ['127.0.0.1', '10'],
     ['127.0.0.2', '30'],
     ['127.0.0.3', '50']]
    
    修改值:

    lines[2][1] = '30'
    
    df.to_csv("test.csv", index=False)
    
    行的内容:

    [['Ip', 'Sites'],
     ['127.0.0.1', '10'],
     ['127.0.0.2', '23'],
     ['127.0.0.3', '50']]
    
    [['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)
    

    您可以使用名为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
    
    最后,要保存这些值,请执行以下操作:

    lines[2][1] = '30'
    
    df.to_csv("test.csv", index=False)
    
    替代方案是:

    • inplace=True一起使用可就地修改文件
    • 用于通过标题而不是索引访问列
      • 这仅在CSV具有标题时有效
    测试CSV:

    Ip,站点
    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)

    中所示,这样我就可以从csv文件中读取并写入csv文件,但我不知道如何重新分配现有文件中的值……您可以发布您已经拥有的读/写代码吗?在某种程度上,您应该拥有Python中的数据,并且可以在写入之前对其进行修改。如果在写入的csv上遇到双换行问题,您可能希望尝试以二进制文件的形式打开该文件:
    writer=csv.writer(open('/tmp/output.csv',wb'))
    您必须关闭写入程序吗?您应该关闭文件描述符,但不应该关闭写入程序。在我的情况下,您可以使用“with”来管理文件;没有关闭编写器会引起问题。更新了使用“with”的答案注意:如果您经常这样做,那么这是非常无效的,因为每次更改值都会对整个文件进行完全重写。(但好吧,CSV可能没有其他方法)尽管它在大多数情况下都有效。有时它会给出
    PermissionError:[Errno 13]权限被拒绝:“file.csv”
    您能怀疑原因吗?这与此代码无关。您似乎没有该文件的写入权限。这是因为该文件仍处于打开状态。结束它,你们都很好。