mis*_*.nz 400 python arrays numpy dataframe pandas
我有兴趣知道如何将pandas数据帧转换为NumPy数组.
数据帧:
import numpy as np
import pandas as pd
index = [1, 2, 3, 4, 5, 6, 7]
a = [np.nan, np.nan, np.nan, 0.1, 0.1, 0.1, 0.1]
b = [0.2, np.nan, 0.2, 0.2, 0.2, np.nan, np.nan]
c = [np.nan, 0.5, 0.5, np.nan, 0.5, 0.5, np.nan]
df = pd.DataFrame({'A': a, 'B': b, 'C': c}, index=index)
df = df.rename_axis('ID')
Run Code Online (Sandbox Code Playgroud)
给
label A B C
ID
1 NaN 0.2 NaN
2 NaN NaN 0.5
3 NaN 0.2 0.5
4 0.1 0.2 NaN
5 0.1 0.2 0.5
6 0.1 NaN 0.5
7 0.1 NaN NaN
Run Code Online (Sandbox Code Playgroud)
我想将其转换为NumPy数组,如下所示:
array([[ nan, 0.2, nan],
[ nan, nan, 0.5],
[ nan, 0.2, 0.5],
[ 0.1, 0.2, nan],
[ 0.1, 0.2, 0.5],
[ 0.1, nan, 0.5],
[ 0.1, nan, nan]])
Run Code Online (Sandbox Code Playgroud)
我怎样才能做到这一点?
作为奖励,是否有可能保留dtypes,像这样?
array([[ 1, nan, 0.2, nan],
[ 2, nan, nan, 0.5],
[ 3, nan, 0.2, 0.5],
[ 4, 0.1, 0.2, nan],
[ 5, 0.1, 0.2, 0.5],
[ 6, 0.1, nan, 0.5],
[ 7, 0.1, nan, nan]],
dtype=[('ID', '<i4'), ('A', '<f8'), ('B', '<f8'), ('B', '<f8')])
Run Code Online (Sandbox Code Playgroud)
或类似的.
有关如何实现这一目标的任何建议?
Use*_*898 346
要将pandas数据帧(df)转换为numpy ndarray,请使用以下代码:
__CODE__
df现在成为numpy ndarray:
df.values
array([[nan, 0.2, nan],
[nan, nan, 0.5],
[nan, 0.2, 0.5],
[0.1, 0.2, nan],
[0.1, 0.2, 0.5],
[0.1, nan, 0.5],
[0.1, nan, nan]])
Run Code Online (Sandbox Code Playgroud)
cs9*_*s95 149
values和as_matrix()!从v0.24.0开始,我们将介绍两种用于从pandas对象获取NumPy数组的新的首选方法:
to_numpy(),定义于Index,Series,和DataFrame对象,和array,仅在Index和Series对象上定义.如果您访问v0.24文档.values,您会看到一条红色警告:
警告:我们建议
DataFrame.to_numpy()改用.
有关详细信息,请参阅v0.24.0发行说明的此部分和此答案.
to_numpy()为了在整个API中更好地保持一致性,to_numpy引入了一种新方法从DataFrames中提取底层NumPy数组.
# Setup.
df = pd.DataFrame({'A': [1, 2, 3], 'B': [4, 5, 6]}, index=['a', 'b', 'c'])
df
A B
a 1 4
b 2 5
c 3 6
Run Code Online (Sandbox Code Playgroud)
df.to_numpy()
array([[1, 4],
[2, 5],
[3, 6]])
Run Code Online (Sandbox Code Playgroud)
如上所述,此方法也定义在Index和Series对象上(参见此处).
df.index.to_numpy()
# array(['a', 'b', 'c'], dtype=object)
df['A'].to_numpy()
# array([1, 2, 3])
Run Code Online (Sandbox Code Playgroud)
默认情况下,返回一个视图,因此所做的任何修改都会影响原始视图.
v = df.to_numpy()
v[0, 0] = -1
df
A B
a -1 4
b 2 5
c 3 6
Run Code Online (Sandbox Code Playgroud)
如果您需要副本,请使用to_numpy(copy=True);
v = df.to_numpy(copy=True)
v[0, 0] = -123
df
A B
a 1 4
b 2 5
c 3 6
Run Code Online (Sandbox Code Playgroud)
如果你需要保留dtypes...
如另一个答案所示,这DataFrame.to_records是一个很好的方法.
df.to_records()
# rec.array([('a', -1, 4), ('b', 2, 5), ('c', 3, 6)],
# dtype=[('index', 'O'), ('A', '<i8'), ('B', '<i8')])
Run Code Online (Sandbox Code Playgroud)
to_numpy遗憾的是,这不可能完成.但是,作为替代方案,您可以使用np.rec.fromrecords:
v = df.reset_index()
np.rec.fromrecords(v, names=v.columns.tolist())
# rec.array([('a', -1, 4), ('b', 2, 5), ('c', 3, 6)],
# dtype=[('index', '<U1'), ('A', '<i8'), ('B', '<i8')])
Run Code Online (Sandbox Code Playgroud)
性能方面,它几乎相同(实际上,使用rec.fromrecords速度更快).
df2 = pd.concat([df] * 10000)
%timeit df2.to_records()
%%timeit
v = df2.reset_index()
np.rec.fromrecords(v, names=v.columns.tolist())
11.1 ms ± 557 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
9.67 ms ± 126 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
Run Code Online (Sandbox Code Playgroud)
to_numpy()(另外array)在两个GitHub问题GH19954和GH23623的讨论结果中添加了.
具体来说,文档提到了基本原理:
[...]
.values还不清楚返回的值是实际数组,它的一些转换,还是pandas自定义数组之一(如Categorical).例如,withPeriodIndex,每次都.values生成一个新ndarray的期间对象.[...]
to_numpy旨在提高API的一致性,这是朝着正确方向迈出的重要一步..values在当前版本中不会弃用,但我预计这可能会在将来某个时候发生,所以我会敦促用户尽快迁移到更新的API.
DataFrame.values 如前所述,行为不一致.
DataFrame.get_values()只是一个包装DataFrame.values,所以上面说的一切都适用.
DataFrame.as_matrix()现已弃用,请勿使用!
ZJS*_*ZJS 127
熊猫有内置的东西......
numpy_matrix = df.as_matrix()
Run Code Online (Sandbox Code Playgroud)
给
array([[nan, 0.2, nan],
[nan, nan, 0.5],
[nan, 0.2, 0.5],
[0.1, 0.2, nan],
[0.1, 0.2, 0.5],
[0.1, nan, 0.5],
[0.1, nan, nan]])
Run Code Online (Sandbox Code Playgroud)
prl*_*900 65
我只是链接DataFrame.reset_index()和DataFrame.values函数来获取数据帧的Numpy表示,包括索引:
In [8]: df
Out[8]:
A B C
0 -0.982726 0.150726 0.691625
1 0.617297 -0.471879 0.505547
2 0.417123 -1.356803 -1.013499
3 -0.166363 -0.957758 1.178659
4 -0.164103 0.074516 -0.674325
5 -0.340169 -0.293698 1.231791
6 -1.062825 0.556273 1.508058
7 0.959610 0.247539 0.091333
[8 rows x 3 columns]
In [9]: df.reset_index().values
Out[9]:
array([[ 0. , -0.98272574, 0.150726 , 0.69162512],
[ 1. , 0.61729734, -0.47187926, 0.50554728],
[ 2. , 0.4171228 , -1.35680324, -1.01349922],
[ 3. , -0.16636303, -0.95775849, 1.17865945],
[ 4. , -0.16410334, 0.0745164 , -0.67432474],
[ 5. , -0.34016865, -0.29369841, 1.23179064],
[ 6. , -1.06282542, 0.55627285, 1.50805754],
[ 7. , 0.95961001, 0.24753911, 0.09133339]])
Run Code Online (Sandbox Code Playgroud)
要获取dtypes,我们需要使用视图将此ndarray转换为结构化数组:
In [10]: df.reset_index().values.ravel().view(dtype=[('index', int), ('A', float), ('B', float), ('C', float)])
Out[10]:
array([( 0, -0.98272574, 0.150726 , 0.69162512),
( 1, 0.61729734, -0.47187926, 0.50554728),
( 2, 0.4171228 , -1.35680324, -1.01349922),
( 3, -0.16636303, -0.95775849, 1.17865945),
( 4, -0.16410334, 0.0745164 , -0.67432474),
( 5, -0.34016865, -0.29369841, 1.23179064),
( 6, -1.06282542, 0.55627285, 1.50805754),
( 7, 0.95961001, 0.24753911, 0.09133339),
dtype=[('index', '<i8'), ('A', '<f8'), ('B', '<f8'), ('C', '<f8')])
Run Code Online (Sandbox Code Playgroud)
met*_*ore 31
您可以使用该to_records方法,但如果它们不是您想要的,那么必须使用dtypes.在我的例子中,从字符串复制DF后,索引类型是字符串(由objectpandas中的dtype 表示):
In [102]: df
Out[102]:
label A B C
ID
1 NaN 0.2 NaN
2 NaN NaN 0.5
3 NaN 0.2 0.5
4 0.1 0.2 NaN
5 0.1 0.2 0.5
6 0.1 NaN 0.5
7 0.1 NaN NaN
In [103]: df.index.dtype
Out[103]: dtype('object')
In [104]: df.to_records()
Out[104]:
rec.array([(1, nan, 0.2, nan), (2, nan, nan, 0.5), (3, nan, 0.2, 0.5),
(4, 0.1, 0.2, nan), (5, 0.1, 0.2, 0.5), (6, 0.1, nan, 0.5),
(7, 0.1, nan, nan)],
dtype=[('index', '|O8'), ('A', '<f8'), ('B', '<f8'), ('C', '<f8')])
In [106]: df.to_records().dtype
Out[106]: dtype([('index', '|O8'), ('A', '<f8'), ('B', '<f8'), ('C', '<f8')])
Run Code Online (Sandbox Code Playgroud)
转换recarray dtype对我来说不起作用,但是已经可以在Pandas中执行此操作:
In [109]: df.index = df.index.astype('i8')
In [111]: df.to_records().view([('ID', '<i8'), ('A', '<f8'), ('B', '<f8'), ('C', '<f8')])
Out[111]:
rec.array([(1, nan, 0.2, nan), (2, nan, nan, 0.5), (3, nan, 0.2, 0.5),
(4, 0.1, 0.2, nan), (5, 0.1, 0.2, 0.5), (6, 0.1, nan, 0.5),
(7, 0.1, nan, nan)],
dtype=[('ID', '<i8'), ('A', '<f8'), ('B', '<f8'), ('C', '<f8')])
Run Code Online (Sandbox Code Playgroud)
请注意,Pandas没有ID在导出的记录数组中正确地设置索引的名称(to )(一个bug?),所以我们从类型转换中获益也是为了纠正它.
目前,Pandas只有8字节的整数i8,和浮点数f8(见本期).
小智 24
它似乎df.to_records()对你有用.您正在寻找的确切功能被要求并to_records指向另一种选择.
我在本地使用你的例子尝试了这个,并且该调用产生的东西与你正在寻找的输出非常相似:
rec.array([(1, nan, 0.2, nan), (2, nan, nan, 0.5), (3, nan, 0.2, 0.5),
(4, 0.1, 0.2, nan), (5, 0.1, 0.2, 0.5), (6, 0.1, nan, 0.5),
(7, 0.1, nan, nan)],
dtype=[(u'ID', '<i8'), (u'A', '<f8'), (u'B', '<f8'), (u'C', '<f8')])
Run Code Online (Sandbox Code Playgroud)
请注意,这是一个recarray而不是一个array.您可以通过调用其构造函数将结果移动到常规numpy数组中np.array(df.to_records()).
Dad*_*han 12
尝试这个:
a = numpy.asarray(df)
Run Code Online (Sandbox Code Playgroud)
这是我从pandas DataFrame制作结构数组的方法.
创建数据框
import pandas as pd
import numpy as np
import six
NaN = float('nan')
ID = [1, 2, 3, 4, 5, 6, 7]
A = [NaN, NaN, NaN, 0.1, 0.1, 0.1, 0.1]
B = [0.2, NaN, 0.2, 0.2, 0.2, NaN, NaN]
C = [NaN, 0.5, 0.5, NaN, 0.5, 0.5, NaN]
columns = {'A':A, 'B':B, 'C':C}
df = pd.DataFrame(columns, index=ID)
df.index.name = 'ID'
print(df)
A B C
ID
1 NaN 0.2 NaN
2 NaN NaN 0.5
3 NaN 0.2 0.5
4 0.1 0.2 NaN
5 0.1 0.2 0.5
6 0.1 NaN 0.5
7 0.1 NaN NaN
Run Code Online (Sandbox Code Playgroud)
定义函数以从pandas DataFrame创建numpy结构数组(不是记录数组).
def df_to_sarray(df):
"""
Convert a pandas DataFrame object to a numpy structured array.
This is functionally equivalent to but more efficient than
np.array(df.to_array())
:param df: the data frame to convert
:return: a numpy structured array representation of df
"""
v = df.values
cols = df.columns
if six.PY2: # python 2 needs .encode() but 3 does not
types = [(cols[i].encode(), df[k].dtype.type) for (i, k) in enumerate(cols)]
else:
types = [(cols[i], df[k].dtype.type) for (i, k) in enumerate(cols)]
dtype = np.dtype(types)
z = np.zeros(v.shape[0], dtype)
for (i, k) in enumerate(z.dtype.names):
z[k] = v[:, i]
return z
Run Code Online (Sandbox Code Playgroud)
使用reset_index使包括索引作为其数据的一部分,新的数据帧.将该数据帧转换为结构数组.
sa = df_to_sarray(df.reset_index())
sa
array([(1L, nan, 0.2, nan), (2L, nan, nan, 0.5), (3L, nan, 0.2, 0.5),
(4L, 0.1, 0.2, nan), (5L, 0.1, 0.2, 0.5), (6L, 0.1, nan, 0.5),
(7L, 0.1, nan, nan)],
dtype=[('ID', '<i8'), ('A', '<f8'), ('B', '<f8'), ('C', '<f8')])
Run Code Online (Sandbox Code Playgroud)
编辑:更新df_to_sarray避免错误调用.encode()与Python 3.感谢约瑟夫·加尔文和宁静 为他们的意见和解决方案.
小智 8
示例数据帧的更简单方法:
df
gbm nnet reg
0 12.097439 12.047437 12.100953
1 12.109811 12.070209 12.095288
2 11.720734 11.622139 11.740523
3 11.824557 11.926414 11.926527
4 11.800868 11.727730 11.729737
5 12.490984 12.502440 12.530894
Run Code Online (Sandbox Code Playgroud)
用:
np.array(df.to_records().view(type=np.matrix))
Run Code Online (Sandbox Code Playgroud)
得到:
array([[(0, 12.097439 , 12.047437, 12.10095324),
(1, 12.10981081, 12.070209, 12.09528824),
(2, 11.72073428, 11.622139, 11.74052253),
(3, 11.82455653, 11.926414, 11.92652727),
(4, 11.80086775, 11.72773 , 11.72973699),
(5, 12.49098389, 12.50244 , 12.53089367)]],
dtype=(numpy.record, [('index', '<i8'), ('gbm', '<f8'), ('nnet', '<f4'),
('reg', '<f8')]))
Run Code Online (Sandbox Code Playgroud)
小智 7
我浏览了上面的答案。“ as_matrix() ”方法有效,但现在已过时。对我来说,有效的是“ .to_numpy() ”。
这将返回一个多维数组。如果您从 Excel 工作表中读取数据并且需要从任何索引访问数据,我会更喜欢使用这种方法。希望这可以帮助 :)
小智 6
从数据框导出到 arcgis 表时遇到了类似的问题,偶然发现了来自 usgs 的解决方案(https://my.usgs.gov/confluence/display/cdi/pandas.DataFrame+to+ArcGIS+Table)。总之你的问题有一个类似的解决方案:
df
A B C
ID
1 NaN 0.2 NaN
2 NaN NaN 0.5
3 NaN 0.2 0.5
4 0.1 0.2 NaN
5 0.1 0.2 0.5
6 0.1 NaN 0.5
7 0.1 NaN NaN
np_data = np.array(np.rec.fromrecords(df.values))
np_names = df.dtypes.index.tolist()
np_data.dtype.names = tuple([name.encode('UTF8') for name in np_names])
np_data
array([( nan, 0.2, nan), ( nan, nan, 0.5), ( nan, 0.2, 0.5),
( 0.1, 0.2, nan), ( 0.1, 0.2, 0.5), ( 0.1, nan, 0.5),
( 0.1, nan, nan)],
dtype=(numpy.record, [('A', '<f8'), ('B', '<f8'), ('C', '<f8')]))
Run Code Online (Sandbox Code Playgroud)
将数据帧转换为其Numpy数组表示形式的两种方法。
mah_np_array = df.as_matrix(columns=None)
mah_np_array = df.values
文件:https://pandas.pydata.org/pandas-docs/stable/genic/pandas.DataFrame.as_matrix.html
小智 5
将数据帧转换为 numpy 数组的简单方法:
import pandas as pd
df = pd.DataFrame({"A": [1, 2], "B": [3, 4]})
df_to_array = df.to_numpy()
array([[1, 3],
[2, 4]])
Run Code Online (Sandbox Code Playgroud)
鼓励使用 to_numpy 以保持一致性。
参考: https: //pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.to_numpy.html
尝试这个:
np.array(df)
array([['ID', nan, nan, nan],
['1', nan, 0.2, nan],
['2', nan, nan, 0.5],
['3', nan, 0.2, 0.5],
['4', 0.1, 0.2, nan],
['5', 0.1, 0.2, 0.5],
['6', 0.1, nan, 0.5],
['7', 0.1, nan, nan]], dtype=object)
Run Code Online (Sandbox Code Playgroud)
更多信息:[ https://docs.scipy.org/doc/numpy/reference/generated/numpy.array.html] 适用于 numpy 1.16.5 和 pandas 0.25.2。