panda或numpy数组数据元素格式化



环境:带有库numpy==1.18.2pandas==1.0.3的Python 3.7.6

import numpy as np
import pandas as pd

np.set_printoptions(suppress=True)
pd.set_option('display.float_format', lambda x: '%.2f' % x)
# does not work ?
data = pd.read_csv("test.csv")
"""
# here is test.csv sample data
at,price
1587690840,15.25
1587690900,15.24
1587690960,15.23
---
"""
x = np.asarray(data)
print(x)
"""
# result:
[[1.58769084e+09 1.52500000e+01]
[1.58769090e+09 1.52400000e+01]
[1.58769096e+09 1.52300000e+01]]
"""

我希望第一个元素转换为不带科学符号的int32,第二个元素转换成float32%.2f

我如何修改x结果如下的代码:

[[1587690840 15.25]
[1587690900 15.24]
[1587690960 15.23]]

我认为使用set_printoptions方法的formatter选项是不可能的。你就不能用apply_over_axes做这个吗?

传统的numpy数组无法存储多个类型,如果您希望打开多个dtype,请参阅结构化数组

array_f = np.zeros(3, dtype={'names':('integers', 'floats'),
'formats':(np.int32, np.float32)})
array_f['integers'] = x[:,0]
array_f['floats'] = x[:,1]
array_f
# array([(1587690840, 15.25), (1587690900, 15.24), (1587690960, 15.23)],
# dtype=[('integers', '<i4'), ('floats', '<f4')])

但老实说,我认为熊猫在这种情况下更有能力。

结构化数据类型:

In [166]: txt = """at,price 
...: 1587690840,15.25 
...: 1587690900,15.24 
...: 1587690960,15.23"""                                                                          
In [167]: data = np.genfromtxt(txt.splitlines(), delimiter=',', names=True, dtype=None, encoding=None) 
In [168]: data                                                                                         
Out[168]: 
array([(1587690840, 15.25), (1587690900, 15.24), (1587690960, 15.23)],
dtype=[('at', '<i8'), ('price', '<f8')])

它有一个int字段和一个float字段。

与浮动加载的内容相同

In [170]: data = np.genfromtxt(txt.splitlines(), delimiter=',', skip_header=1, encoding=None)          
In [171]: data                                                                                         
Out[171]: 
array([[1.58769084e+09, 1.52500000e+01],
[1.58769090e+09, 1.52400000e+01],
[1.58769096e+09, 1.52300000e+01]])

我没有怎么使用set_printoptions,但看起来suppress=True对float没有影响。float有这么大(1.58e9(。两列分别显示:

In [176]: data[:,0]                                                                                    
Out[176]: array([1.58769084e+09, 1.58769090e+09, 1.58769096e+09])
In [177]: data[:,1]                                                                                    
Out[177]: array([15.25, 15.24, 15.23])

和转换为int:的大型浮点

In [178]: data[:,0].astype(int)                                                                        
Out[178]: array([1587690840, 1587690900, 1587690960])

你的pd.read_csv生产什么?

In [189]: pd.DataFrame(data, dtype=None)                                                               
Out[189]: 
0      1
0  1.587691e+09  15.25
1  1.587691e+09  15.24
2  1.587691e+09  15.23
In [190]: pd.DataFrame(Out[168], dtype=None)                                                           
Out[190]: 
at  price
0  1587690840  15.25
1  1587690900  15.24
2  1587690960  15.23

将数据帧转换回数组:

In [191]: Out[190].to_numpy()                                                                          
Out[191]: 
array([[1.58769084e+09, 1.52500000e+01],
[1.58769090e+09, 1.52400000e+01],
[1.58769096e+09, 1.52300000e+01]])
In [193]: Out[190].to_records(index=False)                                                             
Out[193]: 
rec.array([(1587690840, 15.25), (1587690900, 15.24), (1587690960, 15.23)],
dtype=[('at', '<i8'), ('price', '<f8')])

如果最大数字较小,suppress确实有效:

In [201]: with np.printoptions(suppress=True): 
...:     print(data/[100,1]) 
...:                                                                                              
[[15876908.4        15.25]
[15876909.         15.24]
[15876909.6        15.23]]

最新更新