【问题标题】:Pandas read_csv with different date parsers具有不同日期解析器的 Pandas read_csv
【发布时间】:2018-10-10 10:40:48
【问题描述】:

我有一个包含时间序列数据的 csv 文件,第一列为 %Y:%m:%d 格式的日期,第二列为 '%H:%M:%S' 格式的盘中时间。我想将此 csv 文件导入到多索引数据框或面板对象中。

有了这段代码,它已经可以工作了:

    _file_data = pd.read_csv(_file,
                         sep=",",
                         header=0,
                         index_col=['Date', 'Time'],
                         thousands="'",
                         parse_dates=True,
                         skipinitialspace=True
                         )

它以以下格式返回数据:

Date         Time                   Volume
2016-01-04   2018-04-25 09:01:29    53645
             2018-04-25 10:01:29    123
             2018-04-25 10:01:29    1345
             ....
2016-01-05   2018-04-25 10:01:29    123
             2018-04-25 12:01:29    213
             2018-04-25 10:01:29    123

第一个问题: 我想将第二个索引显示为纯时间对象而不是日期时间。为此,我必须在 read_csv 函数中声明两个不同的日期分析器,但我不知道如何。这样做的“最佳”方法是什么?

第二个问题: 创建数据框后,我将其转换为面板对象。你会建议这样做吗?面板对象是这种数据结构的更好选择吗?面板对象有什么好处(缺点)?

【问题讨论】:

  • 第一个问题见this

标签: python pandas dataframe panel-data


【解决方案1】:

第一个问题

您可以创建多个converters 并在字典中定义解析器:

import pandas as pd

temp=u"""Date,Time,Volume
2016:01:04,09:00:00,53645
2016:01:04,09:20:00,0
2016:01:04,09:40:00,0
2016:01:04,10:00:00,1468
2016:01:05,10:00:00,246
2016:01:05,10:20:00,0
2016:01:05,10:40:00,0
2016:01:05,11:00:00,0
2016:01:05,11:20:00,0
2016:01:05,11:40:00,0
2016:01:05,12:00:00,213"""

def converter1(x):
    #convert to datetime and then to times
    return pd.to_datetime(x).time()

def converter2(x):
    #define format of datetime
    return pd.to_datetime(x, format='%Y:%m:%d')

#after testing replace 'pd.compat.StringIO(temp)' to 'filename.csv'
df = pd.read_csv(pd.compat.StringIO(temp), 
                 index_col=['Date','Time'], 
                 thousands="'",
                 skipinitialspace=True,
                 converters={'Time': converter1, 'Date': converter2})

print (df)
                     Volume
Date       Time            
2016-01-04 09:00:00   53645
           09:20:00       0
           09:40:00       0
           10:00:00    1468
2016-01-05 10:00:00     246
           10:20:00       0
           10:40:00       0
           11:00:00       0
           11:20:00       0
           11:40:00       0
           12:00:00     213

有时可以使用内置解析器,例如如果日期格式是YY-MM-DD:

import pandas as pd

temp=u"""Date,Time,Volume
2016-01-04,09:00:00,53645
2016-01-04,09:20:00,0
2016-01-04,09:40:00,0
2016-01-04,10:00:00,1468
2016-01-05,10:00:00,246
2016-01-05,10:20:00,0
2016-01-05,10:40:00,0
2016-01-05,11:00:00,0
2016-01-05,11:20:00,0
2016-01-05,11:40:00,0
2016-01-05,12:00:00,213"""

def converter(x):
    #define format of datetime
    return pd.to_datetime(x).time()

#after testing replace 'pd.compat.StringIO(temp)' to 'filename.csv'
df = pd.read_csv(pd.compat.StringIO(temp), 
                 index_col=['Date','Time'], 
                 parse_dates=['Date'],
                 thousands="'",
                 skipinitialspace=True,
                 converters={'Time': converter})

print (df.index.get_level_values(0))
DatetimeIndex(['2016-01-04', '2016-01-04', '2016-01-04', '2016-01-04',
               '2016-01-05', '2016-01-05', '2016-01-05', '2016-01-05',
               '2016-01-05', '2016-01-05', '2016-01-05'],
              dtype='datetime64[ns]', name='Date', freq=None)

最后可能的解决方案是将datetime 转换为MultiIndex 中的时间set_levels - 处理后:

df.index = df.index.set_levels(df.index.get_level_values(1).time, level=1)
print (df)
                     Volume
Date       Time            
2016-01-04 09:00:00   53645
           09:20:00       0
           09:40:00       0
           10:00:00    1468
2016-01-05 10:00:00     246
           10:00:00       0
           10:20:00       0
           10:40:00       0
           11:00:00       0
           11:20:00       0
           11:40:00     213

第二个问题

pandas 0.20.+ 中的

面板deprecated,将在未来的版本中删除。

【讨论】:

  • 不幸的是,只有最后一个(最不可能的)解决方案有效。使用前两个解决方案 print (df.index.get_level_values(0)) 仍然会打印日期格式。
  • @Krasnars - 你的熊猫版本是什么?
  • 我有熊猫 0.22.0
  • 实际上,它成功了。也许我第一次有类型。谢谢!
【解决方案2】:

要转换为时间序列,请使用pd.to_timedelta

例如:

import pandas as pd
df = pd.DataFrame({"Time": ["2018-04-25 09:01:29", "2018-04-25 10:01:29", "2018-04-25 10:01:29"]})
df["Time"] = pd.to_timedelta(pd.to_datetime(df["Time"]).dt.strftime('%H:%M:%S'))
print df["Time"]

输出:

0   09:01:29
1   10:01:29
2   10:01:29
Name: Time, dtype: timedelta64[ns]

【讨论】:

  • 感谢您的回复。我已经采用了这种方法并且它奏效了。但是,我正在寻找一种在读取 csv 文件时转换数据的方法。
  • @Krasnars - 有问题吗?
猜你喜欢
  • 2023-03-17
  • 2017-12-18
  • 2021-07-23
  • 1970-01-01
  • 1970-01-01
  • 2013-04-15
  • 2017-04-10
  • 1970-01-01
  • 2020-08-03
相关资源
最近更新 更多