【问题标题】:CSV files and PythonCSV 文件和 Python
【发布时间】:2014-09-29 07:20:11
【问题描述】:

我正在编写一个 Python 脚本,该脚本应该合并一些 CSV 文件的一些列(很多,大约 200 个文件)。 所有文件如下所示:

Timestamp; ...; ...; ...; Value; ...
date1;...;...;...; FirstValue;...
date2;...;...;...; SecondValue;...

等等。

我想从第一个文件中提取时间戳和列值。从其他文件中,我只需要列值。

我现在的脚本是:

#!/usr/bin/python
import csv
import os, sys

# Open a file
path = "Z:/myfolder"
dirs = os.listdir( path )
#Conto il numero di file nella cartella
print len(dirs)
#Assegno il nome del primo file
file = dirs[0]

#Apro il primo file per la lettura di timestamp e primo valore (Value)
primofile = csv.reader(open(file, 'rb'), delimiter=";", quotechar='|')
timestamp, firstValue = [], []
#Per ogni riga del primofile
for row in primofile:
    #Copio timestamp
    timestamp.append(row[2])
    #e Value
    firstValue.append(row[15])

with open("provacript.csv", 'wb') as f:
    writer = csv.writer(f, delimiter=';')
    i = 0
    while i < len(timestamp):
        writer.writerow([timestamp[i]] + [firstValue[i]])
        i = i+1

所以在“provascript.csv”中,我有时间戳和第一列,其中包含我在第一个文件中的值。下一步是逐个打开“dirs”列表中的文件,读取“Values”列(第15列),将此列保存在数组中并写入“provascript.csv”。

我的代码是:

for file in dirs:
data = csv.reader(open(file, 'rb'), delimiter=";", quotechar='|')
column = []
for row in data:
    column.append(row[15])

在数组“列”中我应该有值。我必须在“provascript.csv”的新列中添加这些值,然后继续对所有文件做同样的事情。我该怎么做?

我想要类似的东西

TimestampFromFirstFile;ValueFromFirstFile;ValueFromSecondFile;ValueFromThirdFile;...
date1;value;value,value;...
date2;value;value;value;...
date3;value;value;value;...

到目前为止一切顺利。我修复了它(谢谢),但我不想在第一行读取和写入值,我想写下名称的一部分。而不是 Timestamp;Value;Value;Value 我更喜欢 Timestamp;Temperature1;Temperature2;Presence1;Presence2。

我该怎么做?

【问题讨论】:

  • 向我们展示所需输出的样本。
  • 您能否提供输入作为最小示例(如 3 行和 3 列)和相应的输出(如果 ... 不存在,则不显示,如果 value 是实际上是一个int,例如写5。)

标签: python arrays file python-2.7 csv


【解决方案1】:

我应该创建完整的结构,最后我会将它保存在输出文件中(假设文件在它们之间排序)

#create the full structure:  output_rows
primofile = csv.reader(open(file, 'rb'), delimiter=";", quotechar='|')
output_rows = []
for row in primofile:
    output_rows.append([row[2], row[15]])

一旦我们有一个有序的列表列表,用其他文件完成它们

for file in dirs:
    data = csv.reader(open(file, 'rb'), delimiter=";", quotechar='|')
    column = []
    for idx,row in enumerate(data):
        output_rows[idx].append(row[15])

最后保存到文件中

with open("output.csv", 'wb') as f:
    writer = csv.writer(f, delimiter=';')
    for row in output_rows:
        writer.writerow(row)

【讨论】:

  • Traceback(最近一次调用最后):文件“C:/Users/ButoeruG/Desktop/xelena/CsvMerger.py”,第 14 行,在 primofile = csv.reader(open(file , 'rb'), delimiter=";", quotechar='|') IOError: [Errno 2] No such file or directory: 'Scheduled_Archive_(20140804-220703)_(Server_1_TrendLogExtended_PowerV1FreddaC-Ext).csv' 的列表文件是动态的,由系统生成。该文件应该存在。我错了吗?
  • 可能你的数据文件和你的python文件不在同一个目录下?
  • 好吧,我的错。现在错误更改为:文件“C:/Users/ButoeruG/Desktop/xelena/prova/CsvMerger.py”,第 19 行,在 output_rows.append([row[2], row[15]]) IndexError : 列表索引超出范围
  • 似乎 csv primofile 没有 15 行,可以吗?记住索引是从零开始的
  • 看起来 python 文件正在尝试将自身作为 csv 文件打开。我解决了使用 glob 而不是 listdir
【解决方案2】:

你可以用 Pandas 做到这一点:

file1 = pd.read_csv("file1", index_col=0, sep=";", skipinitialspace=1)
file2 = pd.read_csv("file2", index_col=0, sep=";", skipinitialspace=1)
file3 = pd.read_csv("file3", index_col=0, sep=";", skipinitialspace=1)

在这里,您有很多选择,尤其是在读取 csv 时解析日期。

文件 1 是:

           ...  ....1 ....2      Value  ....3
Timestamp                                    
date1      ...   ...   ...   FirstValue   ...
date2      ...   ...   ...  SecondValue   ...

f1 = pd.DataFrame(file1.Value)
f2 = pd.DataFrame(file2.Value)
f3 = pd.DataFrame(file3.Value)

f2

          Value
Timestamp      
date1       AAA
date2       BBB

f3
           Value
Timestamp       
date1        456
date2        123

然后你定义一个递归合并函数:

def recursive_merge(list_df):

    suffixe = range(1,len(list_df)+1)
    merged  = list_df[0]
    for i in range(1,len(list_df)):
        merged = merged.merge(list_df[i], left_index=True, right_index=True,
                                          suffixes=('_%s' %suffixe[i-1], '_%s' %suffixe[i]))
    if len(list_df)%2 !=0 : 
        merged.rename(
            columns = {'Value':"Value_%s" %suffixe[i]}, 
            inplace = True) # if number of recursive merge is odd 
    return merged

并调用:

recursive_merge([f1,f2,f3])

输出:

               Value_1 Value_2  Value_3
Timestamp                              
date1       FirstValue     AAA      456
date2      SecondValue     BBB      123

然后您可以轻松地编写该数据框:

recursive_merge([f1,f2,f3]).to_csv("output.csv")

当然,如果你有 3 个以上的文件,你可以使用 for-loops 和/或函数来打开文件并最终得到一个类似 [f1,f2,f3,...f200] 的列表

希望对你有帮助

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-03-25
    • 1970-01-01
    • 1970-01-01
    • 2020-05-21
    • 2019-05-07
    • 2017-06-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多