2

以下の形式の大きなテキストファイルがあり、CSVファイルに変換したいと思います。CSVファイルの列名は、以下に示すタプルの最初の部分に対応している必要があります。タプルではない行の最初の項目は、常に以下の形式であると想定しても安全です。

その他の問題には、各行に同じフィールドがない場合があることが含まれます。たとえば、ステータスがあるものとないものがあります。同じフィールドの複数のインスタンスがあるものもあります。その場合、タプルの2番目の部分を連結する必要があります(たとえば、スミス氏、グリーン夫人)が、これらは今のところさらに遠い問題です。

[' Message  1 '];['Status', 'Read'];['Message ID', '012434'];['Message Truncation', 'OK'];['Priority', 'Low'];['Sent Time', '15/12/2010 05:56:36']
[' Message  2 '];['ColumnName', 'Read'];['ColumnName2', '012434'];['Message Truncation', 'OK'];['Priority', 'Low'];['Sent Time', '15/12/2010 05:56:36']
[' Message  3 '];['To', 'Mr Smith'];['To', 'Mrs green'];['Message Truncation', 'OK'];['Priority', 'Low'];['Sent Time', '15/12/2013 05:56:36']

..。

私の計画では、ファイル内のすべてのブロックを反復処理して列名を確立してから、これらの列名にデータを追加し始め、必要に応じて空白を残します。辞書のリストをいじって行き詰まってしまったので、これをPythonのように処理する方法を考えています。

行を分割してから、各タプルを辞書に追加する必要があると思います。何か助けはありますか?ありがとう!

for line in file:
    line_split = line.split(';')
4

3 に答える 3

4

ast.literal_eval['something', 'something_else']ブロックをPythonリストに変換するために使用できます。

import ast

column_ids = set()

for line in file:
    columns = [tuple(ast.literal_eval(c)) for c in line.split(';')]
    columns[0] = ('id', columns[0][0]) # Give the first column a 'Id' key
    columns = dict(columns)  # turn the row into a dict
    column_ids.update(columns)

printステートメントを追加し、入力例を使用すると、次のようになります。

{'Status': 'Read', 'Sent Time': '15/12/2010 05:56:36', 'Message Truncation': 'OK', 'Message ID': '012434', 'Priority': 'Low', 'id': ' Message  1 '}
{'Sent Time': '15/12/2010 05:56:36', 'ColumnName2': '012434', 'Message Truncation': 'OK', 'Priority': 'Low', 'ColumnName': 'Read', 'id': ' Message  2 '}
{'Message Truncation': 'OK', 'To': 'Mrs green', 'Priority': 'Low', 'id': ' Message  3 ', 'Sent Time': '15/12/2013 05:56:36'}

column_idsは:

set(['Status', 'Priority', 'ColumnName', 'Message Truncation', 'Message ID', 'To', 'Sent Time', 'ColumnName2', 'id'])
于 2013-01-08T12:14:36.647 に答える
1

純粋なPythonを使用したソリューション...

infile = "listdata.txt"
data = open(infile, "r").readlines()

dataDict = []
columns = []

# Create a dictionary list
for line in data:
    row = line.split(";");
    rowData = {}
    for cell in row:
        cell = cell.strip()[1:-1].split(",")
        if len(cell) > 1:
            rowData[cell[0].strip().strip('"').strip("'")] = cell[1].strip().strip('"').strip("'")
    keys = rowData.keys()
    dataDict.append(rowData)
    columns = list(set(columns) | set(keys))

# Write dictionary list to file
outfile = "listdata.csv"
fp = open(outfile, "w")

for key in columns:
    fp.write(key + ", ")

fp.write("\n")

for data in dataDict:
    for key in columns:
        if key in data:
            fp.write(data[key] + ",")
        else:
            fp.write(",")
    fp.write("\n")

fp.close()

入力:

[' Message  1 '];['Status', 'Read'];['Message ID', '012434'];['Message Truncation', 'OK'];['Priority', 'Low'];['Sent Time', '15/12/2010 05:56:36']
[' Message  2 '];['ColumnName', 'Read'];['ColumnName2', '012434'];['Message Truncation', 'OK'];['Priority', 'Low'];['Sent Time', '15/12/2010 05:56:36']
[' Message  3 '];['To', 'Mr Smith'];['To', 'Mrs green'];['Message Truncation', 'OK'];['Priority', 'Low'];['Sent Time', '15/12/2013 05:56:36']

出力:

Status, Sent Time, To, ColumnName2, Message ID, Message Truncation, Priority, ColumnName, 
Read,15/12/2010 05:56:36,,,012434,OK,Low,,
,15/12/2010 05:56:36,,012434,,OK,Low,Read,
,15/12/2013 05:56:36,Mrs green,,,OK,Low,,

アップデート

これは、同じタイプの複数のエントリを処理してから、で結合し":"ます。

key = cell[0].strip().strip('"').strip("'")
value = cell[1].strip().strip('"').strip("'")
if key in rowData:
    rowData[key] = rowData[key] + ":" + value
else:
    rowData[key] = value
于 2013-01-08T13:22:56.827 に答える
1

パンダの使用:

from pandas import *
import ast
from itertools import chain

df=read_csv('in.txt',sep=';',header=None).applymap(ast.literal_eval).ix[:,1:]
newdf=DataFrame(columns=set(i[0] for i in chain(*df.values)),index=df.index)

for row in df.iterrows():   
    for c in row[1].values:
        newdf[c[0]][row[0]]=c[1]      

newdf.to_csv('out.csv')
于 2013-01-08T13:43:02.290 に答える