我有一个Pandas 数据框,是这样的:

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_idxelement_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数组,我有数百万个条目,inputselement_idx都有几十个条目.在我的机器上花了7个小时才用我的真实数据集完成了这项工作.

我有一种感觉,这可以通过切片来完成,没有循环,但我的try 总是失败-我错过了一些东西.

例如,我try 用以下命令消除内部循环:

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,或者我真的需要这里的循环吗?

推荐答案

我认为您正在搜索旋转数据帧,然后将其转换为NumPy数组:

num_unique_elements = raw_data['element_idx'].nunique()
num_unique_inputs = 3 # a, b, c

df = pd.pivot(raw_data, index='date_idx', columns='element_idx')
df = df.stack(level=0)
print(df.to_numpy().reshape(-1, num_unique_inputs, num_unique_elements))

打印:

[[[10 40]
  [11 41]
  [12 42]]

 [[20 50]
  [21 51]
  [22 52]]

 [[30 60]
  [31 61]
  [32 62]]]

步骤:

df = pd.pivot(raw_data, index='date_idx', columns='element_idx')
print(df)

              a       b       c    
element_idx   0   1   0   1   0   1
date_idx                           
0            10  40  11  41  12  42
1            20  50  21  51  22  52
2            30  60  31  61  32  62

然后用.stack()来reshape 它

df = df.stack(level=0)
print(df)

element_idx   0   1
date_idx           
0        a   10  40
         b   11  41
         c   12  42
1        a   20  50
         b   21  51
         c   22  52
2        a   30  60
         b   31  61
         c   32  62

然后将其转换为NumPy数组:

print(df.to_numpy().reshape(-1, num_unique_inputs, num_unique_elements))

[[[10 40]
  [11 41]
  [12 42]]

 [[20 50]
  [21 51]
  [22 52]]

 [[30 60]
  [31 61]
  [32 62]]]

Python相关问答推荐

如何计算部分聚合数据的统计数据

将词典写入Excel

使用imap-tools时错误,其邮箱地址包含域名中的非默认字符

有没有方法可以修复删除了换码字符的无效的SON记录?

按照行主要蛇扫描顺序对点列表进行排序

如何用symy更新分段函数

Python:在类对象内的字典中更改所有键的索引,而不是仅更改一个键

大Pandas 胚胎中产生组合

如何将ctyles.POINTER(ctyles.c_float)转换为int?

如何使用pandasDataFrames和scipy高度优化相关性计算

将特定列信息移动到当前行下的新行

为什么我的Python代码在if-else声明中的行之前执行if-else声明中的行?

重新匹配{ }中包含的文本,其中文本可能包含{{var}

按列分区,按另一列排序

无法通过python-jira访问jira工作日志(log)中的 comments

Python虚拟环境的轻量级使用

OR—Tools中CP—SAT求解器的IntVar设置值

如何使用Python以编程方式判断和检索Angular网站的动态内容?

在不同的帧B中判断帧A中的子字符串,每个帧的大小不同

(Python/Pandas)基于列中非缺失值的子集DataFrame