【问题标题】:reshape and generate new date data in pandas dataframe在熊猫数据框中重塑并生成新的日期数据
【发布时间】:2019-06-26 20:20:48
【问题描述】:

我有一个熊猫数据框:

import pandas as pd
import numpy as np
d={'ID':['A1','A1','A2','A2','A2'], 'date':['Jan 1','Jan7','Jan4','Jan5','Jan12'],'value':[10,12,3,5,2]}
df=pd.DataFrame(data=d)
df

    ID  date    value
0   A1  Jan 1   10
1   A1  Jan7    12
2   A2  Jan4    3
3   A2  Jan5    5
4   A2  Jan12   2
...
An

我想重塑它,使日期列成为主列,范围从min(date)max(date) 顺序(在本例中为 1 月 1 日到 1 月 12 日)。每个额外的列将是一个单独的 ID,并且值将对应于相应的日期。 我还想用np.linspace(value at first date, value at next date, number of days)“填充”空白,从第一个日期到第一个条目的任何日期都保持不变。

最后,我想:

f={'date':['Jan1','Jan2','Jan3','Jan4','Jan5','Jan6','Jan7','Jan8','Jan9','Jan10','Jan11','Jan12'],
  'A1':[10,10.3,10.7,11,11.3,11.7,12,12,12,12,12,12],
  'A2':[3,3,3,3,5,4.6,4.1,3.7,3.3,2.9,2.4,2]}
df2=pd.DataFrame(data=f)
df2

    date    A1      A2 ... An
0   Jan1    10.0    3.0
1   Jan2    10.3    3.0
2   Jan3    10.7    3.0
3   Jan4    11.0    3.0
4   Jan5    11.3    5.0
5   Jan6    11.7    4.6
6   Jan7    12.0    4.1
7   Jan8    12.0    3.7
8   Jan9    12.0    3.3
9   Jan10   12.0    2.9
10  Jan11   12.0    2.4
11  Jan12   12.0    2.0

我尝试使用 numpy.linspace 生成序列,但是当我尝试附加额外的值时,我没有得到任何值:

A2 = [np.linspace(10,12,10)].append([[12]*4])

np.linspace(10,12,8).append([[12]*5])

给我:

AttributeError: 'numpy.ndarray' object has no attribute 'append'

我正在考虑循环遍历特定元素,但不知道最后如何将它们连接在一起。

任何建议。

【问题讨论】:

  • 这是支点吗?
  • 将使用正确的系列值透视填充日期吗?
  • 为什么Jan7 不是12 for A1 在您的预期输出中?
  • @Erfan 你是对的,问题已更新

标签: pandas dataframe reshape


【解决方案1】:

IIUC,是pivotinterpolate

df['date'] = pd.to_datetime(df['date'], format='%b%d')

(df.pivot(index='date', columns='ID',values='value')
   .asfreq('D')
   .interpolate()
   .bfill()
   .reset_index()
)

输出:

ID       date         A1        A2
0  1900-01-01  10.000000  3.000000
1  1900-01-02  10.333333  3.000000
2  1900-01-03  10.666667  3.000000
3  1900-01-04  11.000000  3.000000
4  1900-01-05  11.333333  5.000000
5  1900-01-06  11.666667  4.571429
6  1900-01-07  12.000000  4.142857
7  1900-01-08  12.000000  3.714286
8  1900-01-09  12.000000  3.285714
9  1900-01-10  12.000000  2.857143
10 1900-01-11  12.000000  2.428571
11 1900-01-12  12.000000  2.000000

注意您要转换为日期时间,因为您将插入这些值。

如果您选择将其转换回来,您可以使用:

df.index = df.index.strftime('%b%d')

输出:

ID            A1        A2
Jan01  10.000000  3.000000
Jan02  10.333333  3.000000
Jan03  10.666667  3.000000
Jan04  11.000000  3.000000
Jan05  11.333333  5.000000
Jan06  11.666667  4.571429
Jan07  12.000000  4.142857
Jan08  12.000000  3.714286
Jan09  12.000000  3.285714
Jan10  12.000000  2.857143
Jan11  12.000000  2.428571
Jan12  12.000000  2.000000

【讨论】:

  • 大致有相同的解决方案,所以如果您不介意,我在您的解决方案中添加了一部分:)。而不是发布新答案
  • 如果我想按月做?我试图设置 .asFreq('M') 但整个结果是 NaN。
  • 在这种情况下,您没有进行上采样。所以你可以使用.resample('M').mean() 而不是.asfreq('M')。如果需要总和,请将 .mean() 替换为 .sum()
  • 太棒了!!谢谢!!
猜你喜欢
  • 2017-08-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多