【问题标题】:How to get the difference between two adjacent columns in csv file using python?如何使用python获取csv文件中两个相邻列之间的差异?
【发布时间】:2017-05-25 15:11:00
【问题描述】:

我是 python 的初学者。我正在尝试使用 python 2.7 获取 csv 文件中两个相邻列之间的差异。

示例输入:

    Temperature        20     21     23     27 ...

    Smoke Obscuration  0.1    0.3    0.6    0.7 ...

    Carbon Dioxide     0.05   0.07   0.08   0.09 ...

    ......

    ......

我想计算两个相邻值之间的差异并得到这样的输出:

    Temperature        0   1      2      4 ...

    Smoke Obscuration  0   0.2    0.3    0.1 ...

    Carbon Dioxide     0   0.02   0.01   0.01 ...

    ......

    ......

据我所知:

import csv
with open("test1.csv", "rb") as f_in, open("test2.csv", "w") as f_out:
    r = csv.reader(f_in)
    w = csv.writer(f_out)
    for row in r:
        for i, v in enumerate(row):
        if i > 1:
                v = (float(row[i]) - float(row[i-1]))
        w.writerow(row)

它给出了一个错误:

ValueError:无法将字符串转换为浮点数:

有人可以帮忙吗?任何指导将不胜感激。

【问题讨论】:

  • 这是一个写得很好的问题。为了将来参考,请尝试使用print 语句来调试您的输出
  • 这是一个奇怪的 csv 文件。它似乎是空格分隔的(创建阅读器时需要delimiter=' '),但第一列名称有时本身有空格(例如,“烟雾遮蔽”)。现在,csv 阅读器认为你有 1 个巨大的列(它正在寻找逗号)。但是因为第一列空格的问题,我想你除了csv.reader之外还需要别的东西来破解它。
  • 试试 pandas 库。这应该很简单,比如两行代码,三行包括“导入”。
  • @vmg 你试过了吗?没有转义列零空格的问题(部分),这会使大多数解析器感到困惑。
  • 也许真正的解决方案是首先修复此文件的来源。如果它是从某个东西导出的,看看你是否可以让那个东西吐出有效的 CSV 数据。如果您是从 excel 复制/粘贴...嗯,这可以解释为什么它看起来如此奇怪。

标签: python csv


【解决方案1】:

您的输入文件不是一个容易解析的 csv 文件。它使用空格来分隔列,但也使用零列内的空格。我认为 csv 模块不会对您有所帮助,但您可以使用几个正则表达式自己解析该行。我的示例通过假设第 0 列名称不包含数字来工作。如果一般情况下不是这样,它就会崩溃。

import re

_col_0_re = re.compile(r'[^\d]+')
_col_x_re = re.compile(r'[\d\.]+')

def get_row(line):
    row = []
    line = line.strip()
    match = _col_0_re.match(line)
    if match:
        # pull out column 0 string
        row.append(line[:match.end()].strip())
        # find the remaining floats on the line
        row.extend(float(col) for col in _col_x_re.findall(line[match.end():]))
    return row

with open("test1.csv", "r") as f_in, open("test2.csv", "w") as f_out:
    for line in f_in:
        row = get_row(line)
        print(row)
        if row:
            diffs = (row[i] - row[i-1] for i in range(2, len(row)))
            diff_str = ''.join('{:10.2f}'.format(diff) for diff in diffs)
            f_out.write('{0:20}  0 {1}\n'.format(row[0], diff_str))

样本数据的输出是

Temperature           0       1.00      2.00      4.00
Smoke Obscuration     0       0.20      0.30      0.10
Carbon Dioxide        0       0.02      0.01      0.01

【讨论】:

  • re 的不错尝试。当我在 Excel 中打开 csv 时,我只得到两列,尽管它在文本编辑器中读得很好。
  • @pylang - 导入到另一个工具与我们在 python 中读取的问题相同。也许它有固定宽度的列和{:10.2f} 格式的一些调整是为了。但我对文件的规则了解得不够多,无法确定。
  • 明白。我们确定文件看起来像呈现的那样吗?作者可能已经编辑了间距以使帖子看起来不错。
  • 非常感谢!这帮助很大! :)
【解决方案2】:

您的源文件可能存在一些间距问题,因此可能难以重现您的特定错误。由于我没有您的原始文件,因此我将您的数据从此处复制到一个文本文件中,然后在 Excel 中将其重新保存为 csv。除了错误的输出之外,我没有遇到您遇到的错误。这表明只要逻辑正确,就可以很好地读取和写入数据。

选项 1:使用 csv 模块

我主要通过使每一行成为可迭代的(即list)来纠正一些逻辑,writerow 方法需要这样做:

import csv

# with open("test1.csv", "r") as f_in, open("test2.csv", "w", newline="") as f_out: # python 3
with open("test1.csv", "r") as f_in, open("test2.csv", "wb") as f_out:            # python 2
    r = csv.reader(f_in)
    w = csv.writer(f_out)
    values = []
    for row in r:
        for i, v in enumerate(row):
            if i == 0:
                values.append(v)
            if i == 1:
                values.append(0)
            if i > 1:
                values.append(float(row[i]) - float(row[i-1]))
        w.writerow(values)
        values = []

选项 2:使用 pandas

您可以pip install pandas 或(conda install pandas,如果您使用Anaconda)并更简单地执行此操作:

import pandas as pd

df = pd.read_csv("test1.csv", header=None, index_col=0)
df2 = df.diff(axis=1)
df2.to_csv("test2.csv", header=False, na_rep=0)

两个选项的输出 csv(在 Excel 中)

在文本编辑器中打开时,这些输出默认以逗号分隔。如果需要,可以使用单独的选项来选择不同的间距(请参阅参考资料)。

试试这些选项。如果您有错误,请确认您的源文件是干净的,以便正确读取它们。现在,使用print 语句来验证您想要的输出。

参考资料:

  1. CSV file written with Python has blank lines between each row
  2. How do I write data to csv file in columns and rows from a list in python?
  3. How to use delimiter for csv in python
  4. delimiter - Writing a pandas to a csv file

【讨论】:

  • 当然可以。假设源文件有效,这一切都可以通过 pandas 之类的库来简化。我的手动步骤是由于缺少包含数据的原始文件。
  • 非常感谢您的帮助和参考! :)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-02-14
  • 1970-01-01
  • 2019-03-26
  • 1970-01-01
  • 1970-01-01
  • 2021-10-11
相关资源
最近更新 更多