Pandas:跨列动态移动值
Pandas: dynamically shifting values across columns
我有以下 df:
sales2001 sales2002 sales2003 sales2004
200012 19.12 0.98
200101 19.1 0.98 2.3
200102 21 0.97 0.8
...
200112 19.12 0.99 2.4
200201 0.98 2.5
200202 0.97 0.8 1.2
我想移动内容以对齐时间间隔视图,如下所示:
sales+1y sales+2y
200012 19.12 0.98
200101 0.98 2.3
200102 0.97 0.8
...
200112 0.99 2.4
200201 0.98 2.5
200202 0.8 1.2
基本上将预测数据点与索引的固定时间间隔对齐。
我尝试使用 iterrows 并动态调用给定索引的列,但无法使其工作。大家有什么建议吗?
使用 with DataFrame.dropna
和 axis=1
删除所有包含至少一个 NaN
:
的列
df1 = (pd.DataFrame(justify(df.values, invalid_val=np.nan, side='right'), index=df.index)
.dropna(axis=1))
如果需要 select 最后一列的位置:
df1 = pd.DataFrame(justify(df.values, invalid_val=np.nan, side='right')[:, -2:],index=df.index)
或者:
df1 = (pd.DataFrame(justify(df.values, invalid_val=np.nan, side='right'), index=df.index)
.iloc[:, -2:])
df1.columns = [f'sales+{i+1}y' for i in range(len(df1.columns))]
print (df1)
sales+1y sales+2y
200012 19.12 0.98
200101 0.98 2.30
200102 0.97 0.80
200112 0.99 2.40
200201 0.98 2.50
200202 0.80 1.20
另一种选择是使用 pd.wide_to_long
和 pivot
:
# here I assume the index name is index
new_df = pd.wide_to_long(df.reset_index(), 'sales', i='index', j='sale_end').reset_index()
# if index is datetime, then use dt.year
new_df['periods'] = new_df['sale_end'] - new_df['index']//100
# pivot
new_df.dropna().pivot(index='index',columns='periods', values='sales')
输出:
periods -1 0 1 2
idx
200012 NaN NaN 19.12 0.98
200101 NaN 19.10 0.98 2.30
200102 NaN 21.00 0.97 0.80
200112 NaN 19.12 0.99 2.40
200201 0.98 2.50 NaN NaN
200202 0.97 0.80 1.20 NaN
我有以下 df:
sales2001 sales2002 sales2003 sales2004
200012 19.12 0.98
200101 19.1 0.98 2.3
200102 21 0.97 0.8
...
200112 19.12 0.99 2.4
200201 0.98 2.5
200202 0.97 0.8 1.2
我想移动内容以对齐时间间隔视图,如下所示:
sales+1y sales+2y
200012 19.12 0.98
200101 0.98 2.3
200102 0.97 0.8
...
200112 0.99 2.4
200201 0.98 2.5
200202 0.8 1.2
基本上将预测数据点与索引的固定时间间隔对齐。 我尝试使用 iterrows 并动态调用给定索引的列,但无法使其工作。大家有什么建议吗?
使用 DataFrame.dropna
和 axis=1
删除所有包含至少一个 NaN
:
df1 = (pd.DataFrame(justify(df.values, invalid_val=np.nan, side='right'), index=df.index)
.dropna(axis=1))
如果需要 select 最后一列的位置:
df1 = pd.DataFrame(justify(df.values, invalid_val=np.nan, side='right')[:, -2:],index=df.index)
或者:
df1 = (pd.DataFrame(justify(df.values, invalid_val=np.nan, side='right'), index=df.index)
.iloc[:, -2:])
df1.columns = [f'sales+{i+1}y' for i in range(len(df1.columns))]
print (df1)
sales+1y sales+2y
200012 19.12 0.98
200101 0.98 2.30
200102 0.97 0.80
200112 0.99 2.40
200201 0.98 2.50
200202 0.80 1.20
另一种选择是使用 pd.wide_to_long
和 pivot
:
# here I assume the index name is index
new_df = pd.wide_to_long(df.reset_index(), 'sales', i='index', j='sale_end').reset_index()
# if index is datetime, then use dt.year
new_df['periods'] = new_df['sale_end'] - new_df['index']//100
# pivot
new_df.dropna().pivot(index='index',columns='periods', values='sales')
输出:
periods -1 0 1 2
idx
200012 NaN NaN 19.12 0.98
200101 NaN 19.10 0.98 2.30
200102 NaN 21.00 0.97 0.80
200112 NaN 19.12 0.99 2.40
200201 0.98 2.50 NaN NaN
200202 0.97 0.80 1.20 NaN