Python:从DataFrame的两列创建结构化的NumPy结构化数组

7
如何从DataFrame的两列创建结构化数组? 我尝试了以下代码:
df = pd.DataFrame(data=[[1,2],[10,20]], columns=['a','b'])
df

    a   b
0   1   2
1   10  20

x = np.array([([val for val in list(df['a'])],
               [val for val in list(df['b'])])])

但是这给我带来了这个:
array([[[ 1, 10],
        [ 2, 20]]])

但是我想要这个:

[(1,2),(10,20)]

谢谢!


1
因为我正在使用的一个包只接受结构化数组作为输入。这为什么很重要呢? - Kim O
因为可能根本不需要创建元组列表,或者从创建元组列表的方式来看,它也是有用的。 - Mazdak
3个回答

12

有几种方法。相对于常规的NumPy数组,您可能会在性能和功能方面遇到一些损失。

记录数组

您可以使用pd.DataFrame.to_recordsindex=False。从技术上讲,这是一个记录数组,但对于许多目的来说,这将足以满足需求。

res1 = df.to_records(index=False)

print(res1)

rec.array([(1, 2), (10, 20)], 
          dtype=[('a', '<i8'), ('b', '<i8')])

结构化数组

您可以通过将行转换为元组,然后为 dtype 参数指定元组列表来手动构造结构化数组。

s = df.dtypes
res2 = np.array([tuple(x) for x in df.values], dtype=list(zip(s.index, s)))

print(res2)

array([(1, 2), (10, 20)], 
      dtype=[('a', '<i8'), ('b', '<i8')])

有什么区别?

很小。 recarrayndarray 的子类,也就是常规的NumPy数组类型。而第二个示例中的结构化数组则是ndarray 类型。

type(res1)                    # numpy.recarray
isinstance(res1, np.ndarray)  # True
type(res2)                    # numpy.ndarray

主要的区别是记录数组可以进行属性查找,而结构化数组会导致 AttributeError 错误:

print(res1.a)
array([ 1, 10], dtype=int64)

print(res2.a)
AttributeError: 'numpy.ndarray' object has no attribute 'a'

相关文章: NumPy的“记录数组”、“结构化数组”或“recarray”


1
使用列表推导式将嵌套的列表转换为元组:
print ([tuple(x) for x in df.values.tolist()])
[(1, 2), (10, 20)]

Detail:

print (df.values.tolist())
[[1, 2], [10, 20]]

编辑:您可以通过 to_records 进行转换,然后使用 np.asarray,请查看 链接:

df = pd.DataFrame(data=[[True, 1,2],[False, 10,20]], columns=['a','b','c'])
print (df)
       a   b   c
0   True   1   2
1  False  10  20

print (np.asarray(df.to_records(index=False)))
[( True,  1,  2) (False, 10, 20)]

1
numpy结构化数组也不是。这个有可能实现吗? - Kim O
@KimO - 你能再解释一下吗? - jezrael
1
结果应为:array([(x,y),(x2,y2)]) - Kim O

0
这是一个一行代码:
list(df.apply(lambda x: tuple(x), axis=1))

或者

df.apply(lambda x: tuple(x), axis=1).values

1
这不是一个NumPy结构化数组,这可能吗? - Kim O
你已经编辑好了吗?第二个版本是你要找的吗? - ags29
是不是有一种方法可以控制字段的类型?例如,如果dataFrame有两列,并且我想要第一列变成“二元类事件指示器”?就像这里解释的那样:https://scikit-survival.readthedocs.io/en/latest/generated/sksurv.ensemble.GradientBoostingSurvivalAnalysis.html#sksurv.ensemble.GradientBoostingSurvivalAnalysis.fit搜索“structured array"……所以是“bool”类型。 - Kim O
1
我强烈建议您不要在结构化数组中使用object数据类型来存储整数。 - jpp

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接