我有一个pandas DataFrame,如下所示:
raw_data = DataFrame({
'date_idx': [0, 1, 2, 0, 1, 2],
'element_idx': [0, 0, 0, 1, 1, 1],
'a': [10, 20, 30, 40, 50, 60],
'b': [11, 21, 31, 41, 51, 61],
'c': [12, 22, 32, 42, 52, 62],
})
我将date_idx
和element_idx
以外的列称为“输入”。我想通过date_idx
-> input_idx
-> element_idx
将它重新组织成一个3d numpy数组,结果如下:
[[[10. 40.]
[11. 41.]
[12. 42.]]
[[20. 50.]
[21. 51.]
[22. 52.]]
[[30. 60.]
[31. 61.]
[32. 62.]]]
我用了两个for循环,效果很好:
date_idx = [0, 1, 2, 0, 1, 2]
element_idx = [0, 0, 0, 1, 1, 1]
raw_data = DataFrame({
'date_idx': date_idx,
'element_idx': element_idx,
'a': [10.0, 20.0, 30.0, 40.0, 50.0, 60.0],
'b': [11.0, 21.0, 31.0, 41.0, 51.0, 61.0],
'c': [12.0, 22.0, 32.0, 42.0, 52.0, 62.0],
})
inputs = ['a', 'b', 'c']
unique_dates = set(date_idx)
unique_elements = set(element_idx)
data = np.zeros(shape=(len(unique_dates), len(inputs), len(unique_elements)), dtype=np.float64)
for i in range(len(raw_data)):
row = raw_data.iloc[i]
date_idx = int(row['date_idx'])
element_idx = int(row['element_idx'])
for input_idx in range(len(inputs)):
data[date_idx][input_idx][element_idx] = float(row[inputs[input_idx]])
print(data)
但是,这是非常缓慢的。对于date_idx
数组,我有数百万个条目,对于inputs
和element_idx
都有数十个条目。在我的机器上需要7个小时才能完成我的真实的数据集。
我有一种感觉,这可以通过切片来完成,没有循环,但我的尝试总是失败-我错过了一些东西。
例如,我尝试使用以下代码消除内部循环:
for i in range(len(raw_data)):
row = raw_data.iloc[i]
date_idx = int(row['date_idx'])
element_idx = int(row['element_idx'])
data[date_idx][:][element_idx] = list(dict(row[inputs]).values())
它失败了:
Traceback (most recent call last):
File "/home/stark/Work/mmr6/test2.py", line 84, in <module>
data[date_idx][:][element_idx] = list(dict(row[inputs]).values())
~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^
ValueError: could not broadcast input array from shape (3,) into shape (2,)
我的问题是,可以使用切片和/或快速技术在普通numpy数组上以这种方式重新组织这个DataFrame吗?或者我真的需要这里的循环吗?
1条答案
按热度按时间sulc1iza1#
我认为你正在搜索旋转 Dataframe ,然后将其转换为numpy数组:
图纸:
步骤:
然后使用
.stack()
对其进行整形然后将其转换为numpy数组: