从数据帧提取行时保留数据类型

2024-06-03 04:16:06 发布

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

pandas{}(例如,使用.loc.iloc)提取单个,产生pandas{}。但是,当处理DataFrame中的异构数据时(即DataFrame的列不都是相同的数据类型),这会导致行中不同列的所有值强制为单个数据类型,因为Series只能有一个数据类型。下面是一个简单的例子来说明我的意思:

import numpy
import pandas

a = numpy.arange(5, dtype='i8')
b = numpy.arange(5, dtype='u8')**2
c = numpy.arange(5, dtype='f8')**3
df = pandas.DataFrame({'a': a, 'b': b, 'c': c})
df.dtypes
# a      int64
# b     uint64
# c    float64
# dtype: object
df
#    a   b     c
# 0  0   0   0.0
# 1  1   1   1.0
# 2  2   4   8.0
# 3  3   9  27.0
# 4  4  16  64.0
df.loc[2]
# a    2.0
# b    4.0
# c    8.0
# Name: 2, dtype: float64

df.loc[2]中的所有值都已转换为float64

有没有一种不进行这种类型转换就提取行的好方法?例如,我可以想象返回一个^{} structured array,但我看不到创建这样一个数组的简单方法


Tags: 数据方法importnumpydataframepandasdfloc
2条回答

另一种方法(但感觉有点粗糙):

您可以使用长度为1的切片器,而不是使用带有lociloc的整数。这将返回长度为1的数据帧,因此iloc[0]包含您的数据。e、 g

In[1] : row2 = df[2:2+1]
In[2] : type(row)
Out[2]: pandas.core.frame.DataFrame
In[3] : row2.dtypes
Out[3]: 
a      int64
b     uint64
c    float64
In[4] : a2 = row2.a.iloc[0]
In[5] : type(a2)
Out[5]: numpy.int64
In[6] : c2 = row2.c.iloc[0]
In[7] : type(c2)
Out[7]: numpy.float64

对我来说,这比两次转换数据类型(一次在行提取期间,一次之后)更为可取,并且比多次使用相同的行规范引用原始数据帧更为清晰(这在计算上可能非常昂贵)

我认为如果pandas有一个DataFrameRow类型用于此变量会更好

正如您已经意识到的,series不允许混合dtypes。但是,如果将其数据类型指定为object,则它允许混合数据类型。因此,您可以将数据帧的数据类型转换为object。每个列都将在数据类型object中,但每个值仍将其数据类型保持为intfloat

df1 = df.astype('O')

Out[10]:
   a   b   c
0  0   0   0
1  1   1   1
2  2   4   8
3  3   9  27
4  4  16  64

In [12]: df1.loc[2].map(type)
Out[12]:
a      <class 'int'>
b      <class 'int'>
c    <class 'float'>
Name: 2, dtype: object

否则,您需要将dataframe转换为np.recarray

n_recs = df.to_records(index=False)

Out[22]:
rec.array([(0,  0,  0.), (1,  1,  1.), (2,  4,  8.), (3,  9, 27.),
           (4, 16, 64.)],
          dtype=[('a', '<i8'), ('b', '<u8'), ('c', '<f8')])

相关问题 更多 >