Numpy获取每列的dtype

vzgqcmou  于 2023-06-23  发布在  其他
关注(0)|答案(4)|浏览(160)

我需要获得每列的类型以正确地对其进行预处理。
目前我通过以下方法来实现:

import pandas as pd

# input is of type List[List[any]]
# but has one type (int, float, str, bool) per column

df = pd.DataFrame(input, columns=key_labels)
column_types = dict(df.dtypes)
matrix = df.values

由于我只使用pandas获取dtypes(每列),并使用numpy获取其他所有内容,因此我希望从项目中删除pandas。
总而言之:有没有一种方法可以从numpy中获得每列的(特定的)dtypes
!或者:有没有一种快速的方法来重新计算ndarray的dtype(在拼接矩阵之后)

eeq64g8w

eeq64g8w1#

如果你给出一个具体的例子会有所帮助,但我将用@jpp's列表来演示:

In [509]: L = [[0.5, True, 'hello'], [1.25, False, 'test']]
In [510]: df = pd.DataFrame(L)
In [511]: df
Out[511]: 
      0      1      2
0  0.50   True  hello
1  1.25  False   test
In [512]: df.dtypes
Out[512]: 
0    float64
1       bool
2     object
dtype: object

pandas不喜欢使用字符串dtypes,所以最后一列是object

In [513]: arr = df.values
In [514]: arr
Out[514]: 
array([[0.5, True, 'hello'],
       [1.25, False, 'test']], dtype=object)

因此,由于列dtypes的混合,pandas使整个object。我不太了解pandas,不知道你是否能更好地控制dtype。
要从L创建一个numpy结构化数组,很明显要做的是:

In [515]: np.array([tuple(row) for row in L], dtype='f,bool,U10')
Out[515]: 
array([(0.5 ,  True, 'hello'), (1.25, False, 'test')],
      dtype=[('f0', '<f4'), ('f1', '?'), ('f2', '<U10')])

这就回答了如何为每个“column”指定不同的dtype的问题。但是请记住,这个数组是1d的,并且有fields而不是columns
但是否可以自动推断或设置dtype,这就比较棘手了。可以从列构建recarray,或者使用np.lib.recfunctions中的某个函数。
如果我使用一个列表'transpose',我可以将每一列格式化为一个单独的numpy数组。

In [537]: [np.array(col) for col in zip(*L)]
Out[537]: 
[array([0.5 , 1.25]),
 array([ True, False]),
 array(['hello', 'test'], dtype='<U5')]

然后用rec.fromarrays将它们加入一个数组:

In [538]: np.rec.fromarrays([np.array(col) for col in zip(*L)])
Out[538]: 
rec.array([(0.5 ,  True, 'hello'), (1.25, False, 'test')],
          dtype=[('f0', '<f8'), ('f1', '?'), ('f2', '<U5')])

或者我可以使用genfromtxtcsv推导字段。

In [526]: np.savetxt('test.txt', np.array(L,object),delimiter=',',fmt='%s')
In [527]: cat test.txt
0.5,True,hello
1.25,False,test

In [529]: data = np.genfromtxt('test.txt',dtype=None,delimiter=',',encoding=None)
In [530]: data
Out[530]: 
array([(0.5 ,  True, 'hello'), (1.25, False, 'test')],
      dtype=[('f0', '<f8'), ('f1', '?'), ('f2', '<U5')])
3zwtqj6y

3zwtqj6y2#

在numpy中,数组的所有条目都具有相同的dtypes。因此,不可能在一列中有专用/快速浮点数,而在另一列中有另一个。
这就是pandas允许您从一个类型的列跳转到另一个类型的点。

vpfxa7rd

vpfxa7rd3#

有没有一种方法可以从numpy中获得每列的(特定的)dtypes
不没有由于你的数据框有混合类型,你的NumPy dtype将是object。这样的数组并不存储在一个连续的内存块中,每一列都有一个固定的数据类型。相反,2d数组中的每个值都由一个指针组成。
您的问题与询问您是否可以获得此列表列表中每个“列”的类型没有什么不同:

L = [[0.5, True, 'hello'], [1.25, False, 'test']]

由于指针集合中的数据没有列结构,因此没有“column dtype”的概念。您可以测试每个子列表中特定索引的每个值的类型。但这就违背了Pandas / NumPy的观点。

ru9i0ody

ru9i0ody4#

为了获得每个列类型并在程序中使用它,可以使用Numpy Structured Arrays
结构化数组是由组织为一系列命名字段的简单数据类型组成的。
它们有一个名为dtype的属性,你可以用它来回答你的问题。
请注意,Numpy也有一个“Record Array”或“recarray”数据类型,这与结构化数组非常相似。但是根据this post,记录数组比结构化数组慢得多,可能是为了方便和向后兼容而保留的。

import numpy as np

# Initialize structured array.
df = np.array([(10, 3.14, 'Hello', True),
                 (20, 2.71, 'World', False)],
                dtype=[
                    ("ci", "i4"),
                    ("cf", "f4"),
                    ("cs", "U16"),
                    ("cb", "?")])

# Basic usage.
print(df)
print(np.size(df))
print(df.shape)
print(df["cs"])
print(df["cs"][0])
print(type(df))
print(df.dtype)
print(df.dtype.names)

# Check exact data type.
print(df.dtype["ci"] == "i4")
print(df.dtype["cf"] == "f4")
print(df.dtype["cs"] == "U16")
print(df.dtype["cb"] == "?")

# Check general data type kind.
print(df.dtype["ci"].kind == "i")
print(df.dtype["cf"].kind == "f")
print(df.dtype["cs"].kind == "U")
print(df.dtype["cb"].kind == "b")

相关问题