我在一次简单的数据转换中被困了一段时间,我希望蜂巢的头脑可以提供帮助。
假设我有一个用于机器学习的Python Pandas数据框,如下所示:
>> trainingDF.ix[0:3,'temp']
Index temp
2011-01-01 00:00:00 9.84
2011-01-01 01:00:00 9.02
2011-01-01 02:00:00 9.02
我们看到索引是一个pandas数据时间序列,而奇异数据列是温度。
我想在此数据框中添加12个要素列,每个要素列指示样本(例如行)是否为给定月份。换句话说,它应该如下所示:
Index temp isJan isFeb isMar isApr isMay etc.
2011-01-01 00:00:00 9.84 1 0 0 0 0 etc.
2011-01-01 01:00:00 9.02 1 0 0 0 0 etc.
2011-01-01 02:00:00 9.02 1 0 0 0 0 etc.
不幸的是,尽管有许多不同的尝试,我似乎无法确定一种优雅的方法来实现这一目标。
任何指针都会非常感激。
答案 0 :(得分:6)
您可以使用get_dummies
来完成艰苦的工作。像
target = pd.DataFrame(0, index=df.index, columns=range(1,13))
dm = pd.get_dummies(df.index.month).set_index(df.index)
target = (target + dm).fillna(0)
target.columns = ['is'+x.capitalize() for x in pd.datetools.MONTHS]
pd.concat([df, target], axis=1)
产生
temp isJan isFeb isMar isApr isMay isJun isJul isAug \
2011-01-01 0.419860 1 0 0 0 0 0 0 0
2011-03-22 0.479502 0 0 1 0 0 0 0 0
2011-06-10 0.687352 0 0 0 0 0 1 0 0
2011-08-29 0.377993 0 0 0 0 0 0 0 1
2011-11-17 0.877410 0 0 0 0 0 0 0 0
isSep isOct isNov isDec
2011-01-01 0 0 0 0
2011-03-22 0 0 0 0
2011-06-10 0 0 0 0
2011-08-29 0 0 0 0
2011-11-17 0 0 1 0
接下来是一些解释。
首先,让我们制作一个测试框架:
>>> index = pd.date_range("2011-01-01", periods=5, freq="80d")
>>> df = pd.DataFrame({"temp": np.random.random(5)}, index=index)
>>> df
temp
2011-01-01 0.566277
2011-03-22 0.965421
2011-06-10 0.854030
2011-08-29 0.780752
2011-11-17 0.148783
现在让我们制作出符合我们想要的东西(我们不应该假设我们每个月都会看到,毕竟;我们的测试示例只有5个月的非零值):
>>> target = pd.DataFrame(0, index=df.index, columns=range(1,13))
>>> target
1 2 3 4 5 6 7 8 9 10 11 12
2011-01-01 0 0 0 0 0 0 0 0 0 0 0 0
2011-03-22 0 0 0 0 0 0 0 0 0 0 0 0
2011-06-10 0 0 0 0 0 0 0 0 0 0 0 0
2011-08-29 0 0 0 0 0 0 0 0 0 0 0 0
2011-11-17 0 0 0 0 0 0 0 0 0 0 0 0
get_dummies
将生成一个指标矩阵:
>>> dm = pd.get_dummies(df.index.month).set_index(df.index)
>>> dm
1 3 6 8 11
2011-01-01 1 0 0 0 0
2011-03-22 0 1 0 0 0
2011-06-10 0 0 1 0 0
2011-08-29 0 0 0 1 0
2011-11-17 0 0 0 0 1
(现在你可以看到为什么我们想在某个地方找到缺少的列。)我们可以将这两个列加在一起:
>>> target = (target + dm).fillna(0)
>>> target
1 2 3 4 5 6 7 8 9 10 11 12
2011-01-01 1 0 0 0 0 0 0 0 0 0 0 0
2011-03-22 0 0 1 0 0 0 0 0 0 0 0 0
2011-06-10 0 0 0 0 0 1 0 0 0 0 0 0
2011-08-29 0 0 0 0 0 0 0 1 0 0 0 0
2011-11-17 0 0 0 0 0 0 0 0 0 0 1 0
除了让它看起来漂亮外,我们都完成了。有很多方法可以获得月份名称;让我们随机选择一个:
>>> pd.datetools.MONTHS
['JAN', 'FEB', 'MAR', 'APR', 'MAY', 'JUN', 'JUL', 'AUG', 'SEP', 'OCT', 'NOV', 'DEC']
>>> target.columns = ['is'+x.capitalize() for x in pd.datetools.MONTHS]
现在这些列按照您的意愿命名。剩下的就是结合一切:
>>> pd.concat([df, target], axis=1)
temp isJan isFeb isMar isApr isMay isJun isJul isAug \
2011-01-01 0.566277 1 0 0 0 0 0 0 0
2011-03-22 0.965421 0 0 1 0 0 0 0 0
2011-06-10 0.854030 0 0 0 0 0 1 0 0
2011-08-29 0.780752 0 0 0 0 0 0 0 1
2011-11-17 0.148783 0 0 0 0 0 0 0 0
isSep isOct isNov isDec
2011-01-01 0 0 0 0
2011-03-22 0 0 0 0
2011-06-10 0 0 0 0
2011-08-29 0 0 0 0
2011-11-17 0 0 1 0