Pandas read_csv:正确解析时间字段

时间:2016-04-27 00:36:17

标签: python pandas

我有以下原始数据,

TranID,TranDate,TranTime,TranAmt
A123456,20160427,02:18,9999.53
B123457,20160426,02:48,26070.33
C123458,20160425,03:18,13779.56
A123459,20160424,03:18,18157.26
B123460,20160423,04:18,215868.15
C123461,20160422,04:18,23695.25
A123462,20160421,05:18,57
B123463,20160420,05:18,64594.24
C123464,20160419,06:18,47890.91
A123465,20160427,06:18,14119.74
B123466,20160426,07:18,2649.6
C123467,20160425,07:18,16757.38
A123468,20160424,08:18,8864.78
B123469,20160423,08:18,26254.69
C123470,20160422,09:18,13206.98
A123471,20160421,09:18,15872.45
B123472,20160420,10:18,197621.18
C123473,20160419,10:18,21048.72

我尝试使用pd read_csv,

导入原始数据

Try1

import numpy as np
import pandas as pd

df = pd.read_csv('MyTest.csv', sep=',', header=0, parse_dates=['TranDate'],
                     usecols=['TranID','TranDate','TranTime','TranAmt'],
                     engine='python')
print(df.dtypes)
df[:5]

输出1

TranID              object
TranDate    datetime64[ns]
TranTime            object
TranAmt            float64
dtype: object
Out[12]:
TranID  TranDate    TranTime    TranAmt
0   A123456 2016-04-27  02:18   9999.53
1   B123457 2016-04-26  02:48   26070.33
2   C123458 2016-04-25  03:18   13779.56
3   A123459 2016-04-24  03:18   18157.26
4   B123460 2016-04-23  04:18   215868.15

Try2

import numpy as np
import pandas as pd

df = pd.read_csv('MyTest.csv', sep=',', header=0, parse_dates=['TranDate', 'TranTime'],
                 usecols=['TranID','TranDate','TranTime','TranAmt'],
                 engine='python')
print(df.dtypes)
df[:5]

输出2

TranID              object
TranDate    datetime64[ns]
TranTime    datetime64[ns]
TranAmt            float64
dtype: object
Out[13]:
TranID  TranDate    TranTime    TranAmt
0   A123456 2016-04-27  2016-04-27 02:18:00 9999.53
1   B123457 2016-04-26  2016-04-27 02:48:00 26070.33
2   C123458 2016-04-25  2016-04-27 03:18:00 13779.56
3   A123459 2016-04-24  2016-04-27 03:18:00 18157.26
4   B123460 2016-04-23  2016-04-27 04:18:00 215868.15

我的混淆与TranTime专栏有关。在Try1中,它显示正确,但dtype是对象。在Try2中,pd将当前日期添加到时间,dtype是datetime。

我希望将此TranTime列视为时间,并希望使用pd的groupby或pivot_table执行聚合。 如果我使用Try1方法,对象dtype是否会影响我的聚合? 如果我使用Try2方法,是否需要剥离Date部分以便使用Time部分?

我精通SAS,其中SAS具有日期,时间和日期时间信息和格式,其中基础数据类型只是数字。因此,我对Python的对象和日期时间dtypes感到困惑。

谢谢, Lobbie

2 个答案:

答案 0 :(得分:1)

  
      
  1. 没有聚合感情,但你会失去时间部分。
  2.   
  3. 不,主要是您可以按.dt accessor
  4. 访问时间部分   
import pandas as pd

df = pd.read_csv('MyTest.csv', parse_dates=[['TranDate', 'TranTime']])
print df

TranDate_TranTime   TranID    TranAmt
0  2016-04-27 02:18:00  A123456    9999.53
1  2016-04-26 02:48:00  B123457   26070.33
2  2016-04-25 03:18:00  C123458   13779.56
3  2016-04-24 03:18:00  A123459   18157.26
4  2016-04-23 04:18:00  B123460  215868.15
5  2016-04-22 04:18:00  C123461   23695.25
6  2016-04-21 05:18:00  A123462      57.00
7  2016-04-20 05:18:00  B123463   64594.24
8  2016-04-19 06:18:00  C123464   47890.91
9  2016-04-27 06:18:00  A123465   14119.74
10 2016-04-26 07:18:00  B123466    2649.60
11 2016-04-25 07:18:00  C123467   16757.38
12 2016-04-24 08:18:00  A123468    8864.78
13 2016-04-23 08:18:00  B123469   26254.69
14 2016-04-22 09:18:00  C123470   13206.98
15 2016-04-21 09:18:00  A123471   15872.45
16 2016-04-20 10:18:00  B123472  197621.18
17 2016-04-19 10:18:00  C123473   21048.72

使用嵌套括号parse_dates=[[]]尽可能将日期/时间解析并管理为一列。

print df.groupby(df.TranDate_TranTime.dt.hour).sum()

      TranAmt
2    36069.86
3    31936.82
4   239563.40
5    64651.24
6    62010.65
7    19406.98
8    35119.47
9    29079.43
10  218669.90

print df.groupby(df.TranDate_TranTime.dt.minute).sum()

      TranAmt
18  710437.42
48   26070.33

得到你想要的东西。

你仍然可以在resampling之后分组,如下所示。

df2 = df.set_index('TranDate_TranTime').resample('60s').sum().dropna()
print df2

                       TranAmt
TranDate_TranTime             
2016-04-19 06:18:00   47890.91
2016-04-19 10:18:00   21048.72
2016-04-20 05:18:00   64594.24
2016-04-20 10:18:00  197621.18
2016-04-21 05:18:00      57.00
2016-04-21 09:18:00   15872.45
2016-04-22 04:18:00   23695.25
2016-04-22 09:18:00   13206.98
2016-04-23 04:18:00  215868.15
2016-04-23 08:18:00   26254.69
2016-04-24 03:18:00   18157.26
2016-04-24 08:18:00    8864.78
2016-04-25 03:18:00   13779.56
2016-04-25 07:18:00   16757.38
2016-04-26 02:48:00   26070.33
2016-04-26 07:18:00    2649.60
2016-04-27 02:18:00    9999.53
2016-04-27 06:18:00   14119.74

print df2.groupby(df2.index.day).sum()

      TranAmt
19   68939.63
20  262215.42
21   15929.45
22   36902.23
23  242122.84
24   27022.04
25   30536.94
26   28719.93
27   24119.27

答案 1 :(得分:1)

在Python中,日期时间通常表示为datetime.datetime个对象。这些效率不高,这就是Pandas使用数字时间戳的原因。

要读取数据(请注意parse_dates参数周围的双括号):

df = pd.read_csv(filename, parse_dates=[['TranDate', 'TranTime']])

>>> df.info()
<class 'pandas.core.frame.DataFrame'>
Int64Index: 18 entries, 0 to 17
Data columns (total 3 columns):
TranDate_TranTime    18 non-null datetime64[ns]
TranID               18 non-null object
TranAmt              18 non-null float64
dtypes: datetime64[ns](1), float64(1), object(1)

>>> df.head()
    TranDate_TranTime   TranID    TranAmt
0 2016-04-27 02:18:00  A123456    9999.53
1 2016-04-26 02:48:00  B123457   26070.33
2 2016-04-25 03:18:00  C123458   13779.56
3 2016-04-24 03:18:00  A123459   18157.26
4 2016-04-23 04:18:00  B123460  215868.15

日期和时间列已连接到一列。获得此时间戳后,可以使用dt访问器轻松访问其属性,例如

>>> df.groupby(df.TranDate_TranTime.dt.hour).TranAmt.sum().head()
TranDate_TranTime
2     36069.86
3     31936.82
4    239563.40
5     64651.24
6     62010.65
Name: TranAmt, dtype: float64

>>> df.groupby(df.TranDate_TranTime.dt.day).TranAmt.sum().head()
TranDate_TranTime
19     68939.63
20    262215.42
21     15929.45
22     36902.23
23    242122.84
Name: TranAmt, dtype: float64

有关Pandas date functionality的更多信息,请参阅Pandas文档。