我需要将存储在pandas.DataFrame
中的数据转换为字节字符串,其中每列可以具有单独的数据类型(整数或浮点)。这是一组简单的数据:
df = pd.DataFrame([ 10, 15, 20], dtype='u1', columns=['a'])
df['b'] = np.array([np.iinfo('u8').max, 230498234019, 32094812309], dtype='u8')
df['c'] = np.array([1.324e10, 3.14159, 234.1341], dtype='f8')
和df看起来像这样:
a b c
0 10 18446744073709551615 1.324000e+10
1 15 230498234019 3.141590e+00
2 20 32094812309 2.341341e+02
DataFrame
知道每列df.dtypes
的类型,所以我想做这样的事情:
data_to_pack = [tuple(record) for _, record in df.iterrows()]
data_array = np.array(data_to_pack, dtype=zip(df.columns, df.dtypes))
data_bytes = data_array.tostring()
这通常可以正常工作但在这种情况下(由于df['b'][0]
中存储的最大值。上面的第二行将元组数组转换为具有给定类型集合的np.array
会导致以下错误:
OverflowError: Python int too large to convert to C long
错误结果(我相信)在第一行中将记录提取为具有单一数据类型的Series
(默认为float64
),并在float64
中选择了表示最大uint64
值不能直接转换回uint64
。
1)由于DataFrame
已经知道每列的类型,有没有办法绕过创建一行元组输入到类型numpy.array
构造函数?或者有没有比上面概述的更好的方法来保留这种转换中的类型信息?
2)是否可以使用每列的类型信息直接从DataFrame
转换为表示数据的字节字符串。
答案 0 :(得分:4)
您可以使用df.to_records()
将数据帧转换为numpy重新排列,然后调用.tostring()
将其转换为字节字符串:
rec = df.to_records(index=False)
print(repr(rec))
# rec.array([(10, 18446744073709551615, 13240000000.0), (15, 230498234019, 3.14159),
# (20, 32094812309, 234.1341)],
# dtype=[('a', '|u1'), ('b', '<u8'), ('c', '<f8')])
s = rec.tostring()
rec2 = np.fromstring(s, rec.dtype)
print(np.all(rec2 == rec))
# True