在NumPy中使用结构化对象数组

2024-09-30 03:22:35 发布

您现在位置:Python中文网/ 问答频道 /正文

比方说,我有一个(x,y)点的数组,其结构如下:

arr = np.array([([1.     ], [2.     ]),
                ([1., 93.], [5., 46.]),
                ([4.     ], [3.     ])],
               dtype=[('x','O'), ('y', 'O')])

也就是说,这些点被分组成这样的最里面的数组。最里面数组的大小可能是任意的,但对于x和y总是相同的

我想做两件事:

a)通过连接最里面的数组的内容来扩展它们,因此对于上面的示例,结果如下所示:

np.array([( 1.,  2.),
          ( 1.,  5.),
          (93., 46.),
          ( 4.,  3.)],
         dtype=[('x','f8'), ('y','f8')])

b)对于每个(最外层)条目,选择y最大的元素:

np.array([( 1.,  2.),
          (93., 46.),
          ( 4.,  3.)],
         dtype=[('x','f8'), ('y','f8')])

我相信应该有一种方法可以有效地做到这一点,而不必使用丑陋的for循环。如果有任何帮助,我将不胜感激。你知道吗

UPD(a和b使用丑陋的循环):

(arr是post开头定义的数组)

(一)

np.array([(x_, y_) for x, y in arr for x_, y_ in zip(x, y)], dtype=[('x','f8'), ('y','f8')])

(二)

np.array([(x[np.argmax(np.array(y))], y[np.argmax(np.array(y))]) for x, y in arr],dtype=[('x','f8'), ('y','f8')])

问题还在于,实际上我不仅有两个字段(x和y),还有77个不同类型的字段(float、integers、booleans)。。。所以这些表达式将增长到许多行。你知道吗


Tags: in示例内容fornp条目数组结构
1条回答
网友
1楼 · 发布于 2024-09-30 03:22:35

使用Pandas,可以将数据存储在平面数据框中,使用group值指示数据来自原始数组的哪一行:

import numpy as np
import pandas as pd
df = pd.DataFrame([
    (0, 1, 2),
    (1, 1, 5),
    (1, 93, 46),
    (2, 4, 3)], dtype='f8', columns=['group', 'x', 'y'])
print(df)
#    group     x     y
# 0    0.0   1.0   2.0
# 1    1.0   1.0   5.0
# 2    1.0  93.0  46.0
# 3    2.0   4.0   3.0

那么第一个操作仅仅是xy列的一部分:

print(df[['x','y']])
#       x     y
# 0   1.0   2.0
# 1   1.0   5.0
# 2  93.0  46.0
# 3   4.0   3.0

第二个操作可以使用groupby/idxmax

print(df.loc[df.groupby('group')['y'].idxmax(), ['x', 'y']])
#       x     y
# 0   1.0   2.0
# 2  93.0  46.0
# 3   4.0   3.0

给定结构化NumPy数组arr,您将不得不循环执行 列表至少列出一次以执行这些操作。因此,您不妨花一次钱将数据组织到一个更好的数据结构中,例如Pandas DataFrame。你知道吗

有一种方法可以将arr转换为df

import numpy as np
import pandas as pd

arr = np.array([([1.     ], [2.     ]),
                ([1., 93.], [5., 46.]),
                ([4.     ], [3.     ])],
               dtype=[('x','O'), ('y', 'O')])

df = pd.DataFrame(arr)
df = (pd.concat({col: df[col].apply(pd.Series).stack() for col in df}, axis=1)
      .reset_index(drop=True))
print(df)

收益率

      x     y
0   1.0   2.0
1   1.0   5.0
2  93.0  46.0
3   4.0   3.0

相关问题 更多 >

    热门问题