【问题标题】:Python: Create structured numpy structured array from two columns in a DataFramePython:从 DataFrame 中的两列创建结构化 numpy 结构化数组
【发布时间】:2018-12-19 04:04:30
【问题描述】:

如何从 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)]

谢谢!

【问题讨论】:

  • 因为我使用的包仅将输入作为结构化数组。为什么这很重要?
  • 因为可能根本不需要创建元组列表,或者它在创建元组列表的方式方面也很有用。

标签: python arrays pandas numpy dataframe


【解决方案1】:

有几种方法。与常规 NumPy 数组相比,您可能会遇到性能和功能方面的损失。

记录数组

您可以将pd.DataFrame.to_recordsindex=False 一起使用。从技术上讲,这是一个record array,但对于许多用途来说这已经足够了。

res1 = df.to_records(index=False)

print(res1)

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

结构化数组

您可以手动构造结构化数组,方法是逐行转换为tuple,然后为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')])

有什么区别?

很少。 recarray 是常规 NumPy 数组类型 ndarray 的子类。另一方面,第二个示例中的结构化数组的类型为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 “record array” or “structured array” or “recarray”

【讨论】:

    【解决方案2】:

    使用列表推导将嵌套的lists 转换为tuples:

    print ([tuple(x) for x in df.values.tolist()])
    [(1, 2), (10, 20)]
    

    详情

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

    编辑:您可以通过to_records 转换,然后转换为np.asarray,检查link

    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)]
    

    【讨论】:

    【解决方案3】:

    这是一个单行:

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

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

    【讨论】:

    • 这不是一个 numpy 结构化数组。这可能吗?
    • 已编辑,您要的是第二个版本吗?
    • 是的!有没有办法控制字段的类型?例如,如果 dataFrame 有两列,我希望第一列变成“二进制类事件指示器”?如此处所述:scikit-survival.readthedocs.io/en/latest/generated/… 搜索“结构化数组”.. 所以“布尔”类型
    • 我强烈建议您不要将 object dtype 用于整数,即使是结构化数组。
    猜你喜欢
    • 1970-01-01
    • 2019-05-08
    • 2016-12-13
    • 2023-03-31
    • 2013-03-12
    • 1970-01-01
    • 1970-01-01
    • 2017-03-08
    • 2023-04-02
    相关资源
    最近更新 更多