Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/286.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 将数据帧转换为rec数组(将对象转换为字符串)_Python_Arrays_Pandas_Numpy - Fatal编程技术网

Python 将数据帧转换为rec数组(将对象转换为字符串)

Python 将数据帧转换为rec数组(将对象转换为字符串),python,arrays,pandas,numpy,Python,Arrays,Pandas,Numpy,我有一个pandas数据框架,其中混合了数据类型(DType),我希望将其转换为numpy结构化数组(或记录数组,在本例中基本相同)。对于纯数字数据帧,使用to_records()方法很容易做到这一点。我还需要将pandas列的数据类型转换为字符串而不是对象,以便使用numpy方法tofile(),该方法将数字和字符串输出到二进制文件,但不会输出对象 简而言之,我需要将带有dtype=object的panda列转换为字符串或unicode数据类型的numpy结构化数组。 下面是一个示例,如果所有

我有一个pandas数据框架,其中混合了数据类型(DType),我希望将其转换为numpy结构化数组(或记录数组,在本例中基本相同)。对于纯数字数据帧,使用
to_records()
方法很容易做到这一点。我还需要将pandas列的数据类型转换为字符串而不是对象,以便使用numpy方法
tofile()
,该方法将数字和字符串输出到二进制文件,但不会输出对象

简而言之,我需要将带有
dtype=object
的panda列转换为字符串或unicode数据类型的numpy结构化数组。

下面是一个示例,如果所有列都有数字(float或int)数据类型,那么代码就足够了

将熊猫作为pd导入
df=pd.DataFrame({'f_num':[1,2,3.],'i_num':[1,2,3],
'char':['a','bb','ccc'],'mixed':['a','bb',1]})
struct\u arr=df.to\u记录(index=False)
打印('struct\u arr',struct\u arr.dtype,'\n')

#据我所知,struct_arr(numpy.record,[('f_num',')对此没有本机功能。例如,序列中所有值的最大长度不存储在任何位置

但是,您可以通过列表理解和f字符串更有效地实现您的逻辑:

data_types = [(col, arr[col].dtype if arr[col].dtype != 'O' else \
               f'U{df[col].astype(str).str.len().max()}') for col in arr.dtype.names]

结合@jpp(为了简洁而列出comp)和@hpaulj(为了速度而将
分解为_记录)的建议,我得出了以下结论,这是更干净的代码,也比我的原始代码快了5倍(通过将示例数据框扩展到10000行以上进行测试):

上面输出的是unicode,而不是字符串,这通常可能更好,但在我的情况下,我需要转换为字符串,因为我正在用fortran读取二进制文件,字符串似乎更容易读入。因此,最好用以下内容替换上面的“格式”行:

formats = [ array.dtype if array.dtype != 'O' 
            else array.astype(str).dtype.str.replace('<U','S') for array in arrays ]
formats=[array.dtype如果array.dtype!='O'

else array.astype(str).dtype.str.replace('
dt=df['mixed'].values.astype(str).dtype
对我很有用。我很想将
分解为_记录
,合并您的数据类型转换。它在列上迭代,并使用
np.rec.fromarrays
构建数组。您看过该函数的代码了吗?我想“分解”更常用于机械,例如失事飞机n关于编程和函数。@hpaulj谢谢,这是一个很好的建议,我在回答我自己的问题时也加入了这个建议。另外,我还很好地使用了“cannibalize”,我只是一开始没有理解它的意思。;-)谢谢!我不想勾选我自己的答案,但这是我所需要的一半(尽管是非常好的一半;-)
data_types = [(col, arr[col].dtype if arr[col].dtype != 'O' else \
               f'U{df[col].astype(str).str.len().max()}') for col in arr.dtype.names]
names = df.columns
arrays = [ df[col].get_values() for col in names ]

formats = [ array.dtype if array.dtype != 'O' 
            else f'{array.astype(str).dtype}' for array in arrays ] 

rec_array = np.rec.fromarrays( arrays, dtype={'names': names, 'formats': formats} )
formats = [ array.dtype if array.dtype != 'O' 
            else array.astype(str).dtype.str.replace('<U','S') for array in arrays ]