在聚合Pandas Dataframe时有效地处理缺少的日期

时间:2013-06-19 09:34:34

标签: python pandas

Summing across rows of Pandas DataframePandas Dataframe object types fillna exception over different datatypes

跟进

我使用

聚合的其中一列
df.groupby(['stock', 'same1', 'same2'], as_index=False)['positions'].sum()

如果缺少数据,这种方法不是很宽容。如果same1,same2等中存在任何缺失数据,则它会填充完全不相关的值。解决方法是在列上执行fillna循环以使用''替换丢失的字符串,并使用零来丢失数字来解决问题。

但我确实有一列缺少日期。列类型是'object',其中包含float类型的nan,以及现有数据字段中缺少的单元格和datetime对象。重要的是我知道数据丢失了,即缺失的指标必须在groupby转换中存活下来。

数据集概述问题:

我用作输入的csv文件是:

Date,Stock,Position,Expiry,same
2012/12/01,A,100,2013/06/01,AA
2012/12/01,A,200,2013/06/01,AA
2012/12/01,B,300,,BB
2012/6/01,C,400,2013/06/01,CC
2012/6/01,C,500,2013/06/01,CC

然后我在文件中读到:

df = pd.read_csv('example', parse_dates=[0])
def convert_date(d):
    '''Converts YYYY/mm/dd to datetime object'''
    if type(d) != str or len(d) != 10: return np.nan
    dd = d[8:]
    mm = d[5:7]
    YYYY = d[:4]
    return datetime.datetime(int(YYYY), int(mm), int(dd))
df['Expiry'] = df.Expiry.map(convert_date)
df

df看起来像:

                 Date Stock  Position               Expiry same
0 2012-12-01 00:00:00     A       100  2013-06-01 00:00:00   AA
1 2012-12-01 00:00:00     A       200  2013-06-01 00:00:00   AA
2 2012-12-01 00:00:00     B       300                  NaN   BB
3 2012-06-01 00:00:00     C       400  2013-06-01 00:00:00   CC
4 2012-06-01 00:00:00     C       500  2013-06-01 00:00:00   CC

可以很容易地更改convert_date函数,以便在Expiry列中弹出缺少数据的任何内容。

然后使用:

df.groupby(['Stock', 'Expiry', 'same'] ,as_index=False)['Position'].sum()

汇总“职位”列。获取 TypeError:无法将datetime.datetime与str 与我插入缺少日期数据的任何非日期进行比较。对于以后的功能来说,重要的是要知道是否缺少Expiry。

1 个答案:

答案 0 :(得分:4)

您需要将日期转换为datetime64[ns] dtype(管理日期时间的工作方式)。对象列不高效,也不能很好地处理日期。 datetime64[ns]使用NaT(非一次)允许缺少值,请参见此处:http://pandas.pydata.org/pandas-docs/dev/missing_data.html#datetimes

In [6]: df['Expiry'] = pd.to_datetime(df['Expiry'])

# alternative way of reading in the data (in 0.11.1, as ``NaT`` will be set
# for missing values in a datelike column)
In [4]: df = pd.read_csv('example',parse_dates=['Date','Expiry'])

In [9]: df.dtypes
Out[9]: 
Date        datetime64[ns]
Stock               object
Position             int64
Expiry      datetime64[ns]
same                object
dtype: object

In [7]: df.groupby(['Stock', 'Expiry', 'same'] ,as_index=False)['Position'].sum()
Out[7]: 
  Stock              Expiry same  Position
0     A 2013-06-01 00:00:00   AA       300
1     B                 NaT   BB       300
2     C 2013-06-01 00:00:00   CC       900

In [8]: df.groupby(['Stock', 'Expiry', 'same'] ,as_index=False)['Position'].sum().dtypes
Out[8]: 
Stock               object
Expiry      datetime64[ns]
same                object
Position             int64
dtype: object