python - 如何把array变成dataframe - 将pandas数据框转换为numpy数组,保留索引
python series转array (7)
我有兴趣知道如何将熊猫数据框转换为包含索引的numpy数组,并设置dtypes。
数据帧:
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')
给
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
将df转换为数组返回:
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]])
不过,我想:
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')])
(或类似)
有关如何完成此任务的任何建议? (我不知道我是否需要一维或二维数组)。我已经看过几篇涉及这方面的文章,但没有具体涉及dataframe.index。
我正在使用to_csv编写数据帧磁盘(并将其读回以创建数组),但我宁愿选择比新到熊猫更为雄辩的东西。
两种将数据帧转换为Numpy数组表示的方法。
mah_np_array = df.as_matrix(columns=None)
mah_np_array = df.values
文件: https://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.as_matrix.html : https://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.as_matrix.html
从数据框导出到arcgis表时遇到了类似的问题,并偶然发现了usgs解决方案( https://my.usgs.gov/confluence/display/cdi/pandas.DataFrame+to+ArcGIS+Table )。 总之你的问题有一个类似的解决方案:
df
Out[109]:
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
Out[113]:
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')]))
感谢菲尔的回答,这很好。
回复
对我不起作用,错误:TypeError:数据类型不明白 - Joseph Garvin Feb 13 at 17:55
我使用python 3,并得到相同的错误。 然后我删除.encode(),然后表达式如下。
types = [(cols[i], df[k].dtype.type) for (i, k) in enumerate(cols)]
那么它的工作。
我只是链接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]])
为了得到dtype,我们需要使用view将这个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')])
要将熊猫数据框(df)转换为numpy ndarray,请使用以下代码:
df = df.values
现在df变成了numpy ndarray:
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]])
这似乎是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')])
请注意,这是一个recarray
而不是一个array
。 你可以通过调用它的构造函数np.array(df.to_records())
将结果移动到常规的numpy数组中。
除了meteore的回答,我找到了代码
df.index = df.index.astype('i8')
不适合我。 所以我把我的代码放在这里,以方便其他人坚持这个问题。
city_cluster_df = pd.read_csv(text_filepath, encoding='utf-8')
# the field 'city_en' is a string, when converted to Numpy array, it will be an object
city_cluster_arr = city_cluster_df[['city_en','lat','lon','cluster','cluster_filtered']].to_records()
descr=city_cluster_arr.dtype.descr
# change the field 'city_en' to string type (the index for 'city_en' here is 1 because before the field is the row index of dataframe)
descr[1]=(descr[1][0], "S20")
newArr=city_cluster_arr.astype(np.dtype(descr))