【问题标题】:Pivot csv data?透视 csv 数据?
【发布时间】:2016-12-27 16:05:16
【问题描述】:

我是 Python 新手,如果这很简单,请原谅。我有一个 csv 文件,其中包含如下数据:

Symbol,date,price
apple, 23/12/2016, 50
apple, 26/12/2016, 51
apple, 27/12/2016, 52
google,23/12/2016, 70
google,26/12/2016, 71
google,27/12/2016, 72

我需要编写一个新的 csv 文件,如下所示:

Date, apple, google
23/12/2016,50,70
26/12/2016,51,71
27/12/2016,52,72

我目前的代码如下。但是,我似乎无法将符号作为列显示。

import csv
import os

csv.register_dialect(
    'mydialect',
    delimiter =',',
    )

symbol, date=[],[]

with open('EB_CUT2.csv',"rt") as dfile:
    thedata = csv.reader(dfile, dialect ='mydialect')
    for row in thedata:
        if row[4] not in date:
            date.append(row[4])
        if row[0] not in symbol:
            symbol.append(row[0])
dfile.close()

ebout = open('EB_CUT.csv',"wt",newline='')
wr = csv.writer(ebout)
for val in date:
    wr.writerow([val])
ebout.close()

【问题讨论】:

  • 请格式化您的 csv 文件,以便我们更好地帮助您
  • Pandas 非常适合这种事情。
  • 这不是转置。转置意味着交换行和列,所以如果你有一个NxM 矩阵,你会得到MxN。在您的示例中,某些列已消失。
  • 你的输出没有意义。
  • 谢谢,是的,看起来 Pandas 是最好的选择。

标签: python python-3.x csv pivot


【解决方案1】:

非熊猫解决方案:

import csv
from datetime import datetime
import os

MY_DIALECT = 'mydialect'
csv.register_dialect(MY_DIALECT, delimiter =',', skipinitialspace=True,)

daily_prices = {}
with open('EB_CUT2.csv', "rt", newline='') as dfile:
    reader = csv.DictReader(dfile, dialect=MY_DIALECT)
    for row in reader:
        date = datetime.date(datetime.strptime(row['date'], '%d/%m/%Y'))
        entry = daily_prices.setdefault(date, {})
        entry[row['Symbol']] = row['price']

all_symbols = sorted(
    set(symbol for value in daily_prices.values() for symbol in value))

with open('EB_CUT.csv', "wt", newline='') as ebout:
    writer = csv.writer(ebout)
    writer.writerow(['Date'] + all_symbols) # header
    for date, prices in sorted(daily_prices.items()):
        row = [date.strftime('%d/%m/%Y')]
        for symbol in all_symbols:
            row.append(prices.get(symbol, ''))
        writer.writerow(row)

如果您想从任何现有的 'EB_CUT.csv' 文件初始化 daily_prices 字典(实际上是上面显示的最后一步的逆操作),听起来您可能从下面的评论中想要在以后合并更多的 csv 文件,下面的代码可以做到这一点:

daily_prices = {}
if os.path.isfile('EB_CUT.csv'):  # existing file?
    # Initialize daily_prices from existing csv file.
    with open('EB_CUT.csv', "rt", newline='') as inf:
        reader = csv.reader(inf)
        next(reader)  # skip header row
        for row in reader:
            date = datetime.date(datetime.strptime(row[0], '%d/%m/%Y'))
            days_prices = daily_prices.setdefault(date, {})
            for symbol, price in row[1:]:
                days_prices[symbol] = price

读取当前 csv 文件以对其进行初始化的另一种方法是始终以您选择的任何格式将与当前 csv 文件对应的daily_prices 数据保存在单独的文件中。使用picklejson 模块可以很容易地写和读回它。

【讨论】:

  • 非常感谢您的帮助,效果很好。我现在只需要添加它,以便对于任何新的日期或符号,它都会附加输出文件,因为我将在第一步中有多个 csv,但我会看看我是否可以解决这个问题。我的 Pandas 解决方案不起作用,因为我遇到了很多 Pandas 错误,可能它没有正确安装在我的 PC 上。再次感谢
  • 不客气。要将数据附加到输出文件,首先从文件中的当前内容初始化 daily_prices 字典(而不是像我的回答中所示的那样从空字典开始),然后从一个或多个 csv 文件中添加数据, 然后最后重写整个输出文件。
【解决方案2】:

熊猫解决方案:

import pandas 

df = pd.read_csv('EB_CUT2.csv', index_col=1, parse_dates=True)
df2 = pd.pivot_table(df, values='price', columns=['Symbol'], index=df.index)
df2.to_csv('EB_CUT.csv')

EB_CUT.csv的内容:

date,apple,google
2016-12-23,50,70
2016-12-26,51,71
2016-12-27,52,72

【讨论】:

    猜你喜欢
    • 2020-03-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-07
    • 2018-04-10
    • 2016-11-21
    • 1970-01-01
    相关资源
    最近更新 更多