我有以下数据框(sim_2005):
Date ELEM1 ELEM2 ... ELEM1133
2005-01-01 0.021 2.455 ... 345.2
2005-01-02 0.321 2.331 ... 355.1
... ... ... ... ...
2005-12-31 0.789 3.456 ... 459.9
[365 rows x 1133 columns]
我需要使用以下格式将其导入(postgresql)数据库:
ID Date ELEM Value
1 2005-01-01 ELEM1 0.021
2 2005-01-02 ELEM1 0.321
...
366 2005-01-01 ELEM2 2.455
367 2005-01-02 ELEM2 2.331
...
402983 2005-01-01 ELEM1133 345.2
402984 2005-01-02 ELEM1133 355.1
...
403348 2005-12-31 ELEM1133 459.9
我正在尽力迭代列并逐步连接它,
for column in sim_2005:
sim_concat = pd.concat([pd.DataFrame(sim_2005.columns.values), sim_2005.ix[:, column]], ignore_index=True)
到目前为止还没有产生我正在寻找的东西。
我也试过pandas pivot function,groupby等...但我想我对pandas和python的理解一般不足以进行这种转换。有什么帮助吗?
修改
谢谢,pd.melt就是答案!
sim_2005_melted = pd.melt(sim_2005, id_vars=sim_2005.index.name, value_vars=list(sim_2005.columns.values), var_name='ELEM', value_name='Q_sim').sort(columns='Date')
结果:
ID Date ELEM Q_sim
1 NaN ELEM1 0.021
2 NaN ELEM1 0.321
...
366 NaN ELEM2 2.455
367 NaN ELEM2 2.331
...
402983 NaN ELEM1133 345.2
402984 NaN ELEM1133 355.1
由于某种原因,日期时间索引没有被转移,但整体结构正是我想要的!
答案 0 :(得分:1)
看起来你正在用pandas
术语进行“从宽到窄”的转换。一种方法是使用melt
。
在这种情况下,您可以执行以下操作:
pd.melt(df, id_vars=['Date'], value_vars=['ELEM1', 'ELEM2']).sort(columns='Date')
表示具有两个“宽”列['ELEM1', 'ELEM2']
的数据框。对于示例中的~1K列,您显然不是手动编写它们,而是使用某种列表理解来创建value_vars
。
示例强>
df = pd.DataFrame({
'Date': range(4),
'ELEM1': range(1, 5),
'ELEM2': range(11, 15),
'ELEM2': range(-5, -1)
})
>> df
Date ELEM1 ELEM2
0 0 1 -5
1 1 2 -4
2 2 3 -3
3 3 4 -2
>> pd.melt(df, id_vars=['Date'], value_vars=['ELEM1', 'ELEM2']).sort(columns='Date')
Date variable value
0 0 ELEM1 1
4 0 ELEM2 -5
1 1 ELEM1 2
5 1 ELEM2 -4
2 2 ELEM1 3
6 2 ELEM2 -3
3 3 ELEM1 4
7 3 ELEM2 -2