公众号原文首发:https://mp.weixin.qq.com/s/4RYfYc8_2vNxvq_B1bZrUA

为什么用 Pandas?

你好,我是悦创。
通过对 Numpy 的学习,咱们发现 Numpy 的性能的确弱小且易用。然而再弱小的工具也有其局限性。

例如 Numpy 是基于数组的运算,然而在理论工作中,咱们的数据元素会非常复杂,会同时蕴含文字格局、数字格局、工夫格局等,显然 Numpy就不实用了。

通常咱们说 Numpy 是基于数组格局构建的一个数组运算工具,而 Pandas 是基于 Numpy 构建的结构化数据处理工具。对 Pandas 来讲,数据格式失去了裁减,提供了工夫序列能力,并且可能同时包容多种数据格式,并且提供了灵便的缺失值解决工具,性能失去极大地拓展。

Pandas 罕用的数据结构有两种:SeriesDataFrame 。其中 Series 是一个带有名称和索引的一维数组,而 DataFrame 则是用来示意多维的数组构造。

总结如下:

  • 疾速高效的数据结构
  • 智能的数据处理能力
  • 不便的文件存取性能
  • 科研及商业利用宽泛

对于 Pandas 有两种根底的数据结构,基本上咱们在应用的时候就是解决 Series 和 DataFrame。

  • Series:真正的数据是只有一列的,索引列咱们是不算进去的。
索引数据
A10
B30
C20
D40
  • DataFrame:好几个 Series 联合起来,也就是有好几列的数据联合起来。
电影评分评分人数
0血观音7.938478
1大佛普拉斯8.658112
2华盛顿邮报8.230773
3三块广告牌8.7250524

装置 Pandas

Windows 零碎:

pip install pandas

Mac 零碎:

pip3 install pandas

新建一个 Python 文件

  • 导入模块
In [1]: import pandas as pd

Pandas 的根底类型1——Series

  • 创立一个 Series 类型的数据
In [2]: data = pd.Series([1, 3, 5, 7])
  • Series() 里间接填一个由数字组成的列表
In [3]: list_data = [1, 3, 5, 7]In [4]: data = pd.Series(list_data)  In [5]: dataOut[5]:0    11    32    53    7dtype: int64

由后果咱们可知,右边把咱们的索引也列出来了,左边对应的数值也列出来了。底部通知你这个 Series 的数据类型 int64。「如果外面最低的数据类型是 float 那后果也会变成浮点数。」

  • 获取 Series 数据的值
In [6]: data.valuesOut[6]: array([1, 3, 5, 7])
  • 获取 Series 数据的索引
In [7]: data.indexOut[7]: RangeIndex(start=0, stop=4, step=1)
  • 创立非凡的索引值
    有时候,咱们索引的名称比拟非凡不是咱们本来简略的数字了,有可能是 a、b、c、d 之类的。这个时候就咱们该如何指定索引值呢?间接在 Series 创立的时候指定一下就 ok 了。
In [7]: data = pd.Series(list_data, index=['a', 'b', 'c', 'd'])In [8]: dataOut[8]:a    1b    3c    5d    7dtype: int64

这里咱们就在创立的时候进行的索引值的指定,那咱们如果要在创立之后批改索引呢?

  • 批改索引值名称
In [9]: data.index = ['j', 'k', 'x', 'f'] # 长度须要和数组的长度一样In [10]: dataOut[10]:j    1k    3x    5f    7dtype: int64
  • 获取 Series 数据长度
In [11]: len(data)Out[11]: 4
  • 获取数组中的某个数据
In [12]: data['k'] # data[1]Out[12]: 3
  • 获取数组中多个数据「不间断」「第一个中括号:通知程序说,我要索引一下;第二个中括号:用来获取多个数据,一个数据则不必」
In [13]: data[['k', 'f']]Out[13]:k    3f    7dtype: int64
  • 获取数组中多个数据「间断的」
In [14]: data[1:3] # 也能够有步长Out[14]:k    3x    5dtype: int64
  • 计算反复元素呈现的次数
In [17]: list_data1 = [1, 1, 1, 3, 5, 5, 7, 7, 9]In [18]: data1 = pd.Series(list_data1)In [19]: data1.value_counts()Out[19]:1    37    25    29    13    1dtype: int64
  • 判断某个索引值是否存在
In [21]: list_data2 = [1, 3, 5, 7]In [22]: data3 = pd.Series(list_data2, index=['a', 'j', 'b', 'f'])In [23]: 'a' in data3Out[23]: TrueIn [24]: 'z' in data3Out[24]: False
  • 查看是否蕴含在系列
In [4]: s = pd.Series(['lama', 'cow', 'lama', 'beetle', 'lama', 'hippo'], name='animal')In [5]: s.isin(['cow', 'lama'])Out[5]:0     True1     True2     True3    False4     True5    FalseName: animal, dtype: boolIn [6]: s.isin(['lama'])Out[6]:0     True1    False2     True3    False4     True5    FalseName: animal, dtype: bool
  • 从字典创立一个 Series 类型的数据
In [26]: dict_data = {"BeiJing": 1000, "Shanghai": 800, "Shenzhen": 500}In [27]: data4 = pd.Series(dict_data)In [28]: data4Out[28]:BeiJing     1000Shanghai     800Shenzhen     500dtype: int64
  • 给数据传入索引值「由字典创立的数组,当咱们指定的索引超出时,会主动 nan 填充」
In [33]: dict_data = {"BeiJing": 1000, "Shanghai": 800, "Shenzhen": 500}In [34]: index_list = ["Guangzhou", "BeiJing", "Shanghai", "Shenzhen"]In [35]: data5 = pd.Series(dict_data, index=index_list)In [36]: data5Out[36]:Guangzhou       NaNBeiJing      1000.0Shanghai      800.0Shenzhen      500.0dtype: float64
  • 检测哪些数据是缺失的(空的)「检测非空用 notnull() 」
In [37]: data5.isnull()Out[37]:Guangzhou     TrueBeiJing      FalseShanghai     FalseShenzhen     Falsedtype: bool
  • 数组运算
In [10]: data5 * 5Out[10]:Guangzhou       NaNBeiJing      5000.0Shanghai     4000.0Shenzhen     2500.0dtype: float64
  • 数组运算反对 numpy 数组运算
In [12]: import numpy as npIn [13]: np.square(data5) # 求平方Out[13]:Guangzhou          NaNBeiJing      1000000.0Shanghai      640000.0Shenzhen      250000.0dtype: float64
  • 两个数组相加「两个的数组的长度能够不一样,程序也能够不一样」
In [14]: dict_data1 = {"BeiJing": 1000, "Shanghai": 800, "Shenzhen": 500}    ...: dict_data2 = {"BeiJing": 1000, "Shanghai": 800, "Shenzhen": 500}    ...:    ...: index_list = ["Guangzhou", "BeiJing", "Shanghai", "Shenzhen"]    ...: data1 = pd.Series(dict_data1, index=index_list)    ...: data2 = pd.Series(dict_data2)In [15]: data1 + data2Out[15]:BeiJing      2000.0Guangzhou       NaNShanghai     1600.0Shenzhen     1000.0dtype: float64
In [16]: data1 = pd.Series(dict_data1, index=index_list)    ...: data2 = pd.Series(dict_data2, index=index_list)In [17]: data1 + data2Out[17]:Guangzhou       NaNBeiJing      2000.0Shanghai     1600.0Shenzhen     1000.0dtype: float64
In [21]: data1 = pd.Series([1, 3, 5, 6, 7, 8])In [22]: data2 = pd.Series([2, 4, 6, 8, 9])In [23]: data1 + data2Out[23]:0     3.01     7.02    11.03    14.04    16.05     NaNdtype: float64
  • 设定 Series 对象的 name 和索引名称「相似于给一个表格取个名称,给索引值取个名称」
In [25]: dict_data = {"BeiJing": 1000, "Shanghai": 800, "Shenzhen": 500}In [26]: data = pd.Series(dict_data)In [27]: data.name = 'City Data'In [28]: data.index.name = 'City'In [29]: dataOut[29]:CityBeiJing     1000Shanghai     800Shenzhen     500Name: City Data, dtype: int64
  • 当然咱们还能够在创立为数组取名字
In [30]: dict_data = {"BeiJing": 1000, "Shanghai": 800, "Shenzhen": 500}In [31]: data = pd.Series(dict_data, name='City Data')In [32]: dataOut[32]:BeiJing     1000Shanghai     800Shenzhen     500Name: City Data, dtype: int64

Pandas 的根底类型2——DataFrame

  • 创立一个 DataFrame 类型的数据
In [39]: dict_data = {    ...: 'Student': ['lilei', 'hanmeimei', 'aiyuechuang'],    ...: 'Score': [99, 100, 135],    ...: 'Gender': ['M', 'F', 'M']    ...: }In [40]: data = pd.DataFrame(dict_data)In [41]: dataOut[41]:       Student  Score Gender0        lilei     99      M1    hanmeimei    100      F2  aiyuechuang    135      M
  • 指定 DataFrame 数据的列程序「如果呈现后果程序不一样,这个是失常景象」
In [42]: data = pd.DataFrame(dict_data, columns=['Gender', 'Score', 'Student'])  # 指定列的程序In [43]: dataOut[43]:  Gender  Score      Student0      M     99        lilei1      F    100    hanmeimei2      M    135  aiyuechuang
  • 获取 DataFrame 数据的列名称
In [45]: data.columnsOut[45]: Index(['Gender', 'Score', 'Student'], dtype='object')
  • 指定 DataFrame 数据的索引值
In [46]: data = pd.DataFrame(dict_data,    ...:                     columns=['Gender', 'Score', 'Student'],    ...:                     index=['a', 'b', 'c'])In [47]: dataOut[47]:  Gender  Score      Studenta      M     99        lileib      F    100    hanmeimeic      M    135  aiyuechuang
  • 获取 DataFrame 数据中的某一列数据
In [48]: data['Student'] #  办法一Out[48]:a          lileib      hanmeimeic    aiyuechuangName: Student, dtype: objectIn [49]: data.Student  #  办法二Out[49]:a          lileib      hanmeimeic    aiyuechuangName: Student, dtype: object
  • 获取 DataFrame 数据中的某一行数据
  1. 依据行编号
In [51]: data.iloc[0]Out[51]:Gender         MScore         99Student    lileiName: a, dtype: object
In [59]: data.loc[['a', 'c']] # 指定多行数据Out[59]:  Gender  Score      Studenta      M     99        lileic      M    135  aiyuechuang
In [60]: data[0:2]Out[60]:  Gender  Score    Studenta      M     99      lileib      F    100  hanmeimei

  1. 依据行索引
In [52]: data.loc['a']Out[52]:Gender         MScore         99Student    lileiName: a, dtype: object
  • 切片「单列数据」
In [53]: slice_data = data['Student']In [54]: slice_dataOut[54]:a          lileib      hanmeimeic    aiyuechuangName: Student, dtype: object
  • 切片「获取多列数据」
In [56]: slice_data = data[['Student', 'Gender']]In [57]: slice_dataOut[57]:       Student Gendera        lilei      Mb    hanmeimei      Fc  aiyuechuang      M

留神!切片失去的数据对应的还是原始数据,任何批改都会反映到原始数据上

In [62]: dict_data = {    ...:     'Student': ['lilei', 'hanmeimei', 'aiyuechuang'],    ...:     'Score': [99, 100, 135],    ...:     'Gender': ['M', 'F', 'M']    ...:     }    ...:    ...: data = pd.DataFrame(dict_data,    ...:                     columns=['Gender', 'Score', 'Student'],    ...:                     index=['a', 'b', 'c'])    ...: slice_data = data['Score']  # data[['Score']]    ...: """    ...: 第一种 ['Score'] 在确定只提取一个的话应用这种办法;    ...: 第二种 [['Score']] 在不确定或者确定会有提取多个的话,举荐应用这个办法。    ...: """    ...: slice_data[0] = 999  # 当咱们在切片的时候,如果只是单纯的切片「不带 copy」没有操作不会出    ...: 现"正告" 如果进行的赋值或者批改,则会呈现正告。「算是提醒吧,也是比拟智能的一个点」/usr/local/bin/ipython:15: SettingWithCopyWarning:A value is trying to be set on a copy of a slice from a DataFrameSee the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copyIn [63]: dataOut[63]:  Gender  Score      Studenta      M    999        lileib      F    100    hanmeimeic      M    135  aiyuechuang

想要一份正本不影响原始数据?

请用 data['score'].copy()

In [64]: slice_data = data['Score'].copy()    ...: slice_data[0] = 999In [65]: dataOut[65]:  Gender  Score      Studenta      M     99        lileib      F    100    hanmeimeic      M    135  aiyuechuang

如果如果同时切片数据不止一个,那批改之后的数据变成这样:

In [75]: slice_data = data[['Score', 'Student']].copy()    ...: slice_data.iloc[0] = 999In [76]: slice_dataOut[76]:   Score      Studenta    999          999b    100    hanmeimeic    135  aiyuechuang

留神:如果你是如此操作提取数据的话—— data[['Score']] ,在下一步中批改数据中如果是这样操作的话:slice_data[0] = 999 失去的后果是 增加新的列。所以,就须要应用 iloc 或 loc 来指定了。

In [73]: slice_data = data[['Score', 'Student']].copy()    ...: slice_data[0] = 999 #  slice_data[列名] = 列值    ...: slice_dataOut[73]:   Score      Student    0a     99        lilei  999b    100    hanmeimei  999c    135  aiyuechuang  999
  • 批改 DataFrame 数据中的某一列数据
In [77]: dataOut[77]:  Gender  Score      Studenta      M     99        lileib      F    100    hanmeimeic      M    135  aiyuechuangIn [78]: data['Score'] = 120In [79]: dataOut[79]:  Gender  Score      Studenta      M    120        lileib      F    120    hanmeimeic      M    120  aiyuechuangIn [80]: data['Score'] = 10, 20, 30 #  [10, 20, 30]、(10, 20, 30)In [81]: dataOut[81]:  Gender  Score      Studenta      M     10        lileib      F     20    hanmeimeic      M     30  aiyuechuang
In [88]: data['Score'] = range(95, 98)In [89]: dataOut[89]:  Gender  Score      Studenta      M     95        lileib      F     96    hanmeimeic      M     97  aiyuechuang
  • 传入 Series 类型批改 DataFrame 数据中的某一列数据
In [90]: series_data = pd.Series([1, 3, 5])In [91]: data['Score'] = series_dataIn [92]: dataOut[92]:  Gender  Score      Studenta      M    NaN        lileib      F    NaN    hanmeimeic      M    NaN  aiyuechuangIn [94]: series_data = pd.Series([1, 3, 5], index=['a', 'b', 'c'])In [95]: data['Score'] = series_dataIn [96]: dataOut[96]:  Gender  Score      Studenta      M      1        lileib      F      3    hanmeimeic      M      5  aiyuechuang

如果 Series 的数据过长,则主动疏忽:

In [97]: series_data = pd.Series([1, 3, 5, 7], index=['a', 'b', 'c', 'd'])In [98]: data['Score'] = series_dataIn [99]: dataOut[99]:  Gender  Score      Studenta      M      1        lileib      F      3    hanmeimeic      M      5  aiyuechuang
  • 删除 DataFrame 数据中的某一列数据
In [102]: del data['Score']In [103]: dataOut[103]:  Gender      Studenta      M        lileib      F    hanmeimeic      M  aiyuechuang
  • 删除一行或一列:drop 函数
DataFrame.drop(labels=None, axis=0, index=None, columns=None, inplace=False)# labels 就是要删除的行列的名字,用列表给定# axis 默认为0,指删除行,因而删除 columns 时要指定 axis=1;# index 间接指定要删除的行# columns 间接指定要删除的列# inplace=False,默认该删除操作不扭转原数据,而是返回一个执行删除操作后的新 dataframe;# inplace=True,则会间接在原数据上进行删除操作,删除后无奈返回。

因而,删除行列有两种形式:

  1. labels=None,axis=0 的组合
  2. index 或 columns 间接指定要删除的行或列
In [111]: df = pd.DataFrame(np.arange(12).reshape(3,4), columns=['A', 'B', 'C', 'D'])In [112]: dfOut[112]:   A  B   C   D0  0  1   2   31  4  5   6   72  8  9  10  11#Drop columns,两种办法等价In [113]: df.drop(['B', 'C'], axis=1)Out[113]:   A   D0  0   31  4   72  8  11In [114]: df.drop(columns=['B', 'C'])Out[114]:   A   D0  0   31  4   72  8  11# 第一种办法下删除 column 肯定要指定 axis=1,否则会报错In [115]: df.drop(['B', 'C'])---------------------------------------------------------------------------KeyError                                  Traceback (most recent call last)KeyError: "['B' 'C'] not found in axis"#Drop rowsIn [116]: df.drop([0, 1])Out[116]:   A  B   C   D2  8  9  10  11In [117]: df.drop(index=[0, 1])Out[117]:   A  B   C   D2  8  9  10  11
  • 依据新的索引重新排列数据
In [120]: dict_data = {     ...:     'Student': ['lilei', 'hanmeimei', 'aiyuechuang'],     ...:     'Score': [99, 100, 135],     ...:     'Gender': ['M', 'F', 'M']     ...: }In [121]: data = pd.DataFrame(dict_data,     ...:     columns=['Gender', 'Score', 'Student'],     ...:     index=['a', 'b', 'c'])In [122]: data.reindex(['b', 'a', 'c'])Out[122]:  Gender  Score      Studentb      F    100    hanmeimeia      M     99        lileic      M    135  aiyuechuang

如果,咱们在从新排序的时候,多填了一个 d 那绝对应 d 的几个地位的数据 pandas 会主动帮你填上 NaN。

In [123]: data.reindex(['b', 'a', 'c', 'd'])Out[123]:  Gender  Score      Studentb      F  100.0    hanmeimeia      M   99.0        lileic      M  135.0  aiyuechuangd    NaN    NaN          NaN

如果,咱们想在多填了之后指定数据呢?

将缺失地位填0

In [124]: data.reindex(['b', 'a', 'c', 'd'], fill_value=0)Out[124]:  Gender  Score      Studentb      F    100    hanmeimeia      M     99        lileic      M    135  aiyuechuangd      0      0            0
  • 将缺失地位通过插值法计算并补上内容
In [125]: data.reindex(['b', 'a', 'c', 'd'], method='ffill')Out[125]:  Gender  Score      Studentb      F    100    hanmeimeia      M     99        lileic      M    135  aiyuechuangd      M    135  aiyuechuangIn [126]: data.reindex(['b', 'a', 'c', 'd'], method='bfill')Out[126]:  Gender  Score      Studentb      F  100.0    hanmeimeia      M   99.0        lileic      M  135.0  aiyuechuangd    NaN    NaN          NaN
  • 扔掉蕴含缺失的数据(NaN)的行「例如:咱们数据量很大的时候,有可能想把空值去掉,应用 dropna 来去掉,只有这一行有一个空数据,就会去掉。」这里代码为了不便演示,就先不应用 IPython。
import numpy as npimport pandas as pddict_data = {    'Student': ['lilei', 'hanmeimei', 'aiyuechuang'],    'Score': [99, 100, 135],    'Gender': ['M', 'F', 'M']}data = pd.DataFrame(dict_data,    columns=['Gender', 'Score', 'Student', 'Age'],    index=['a', 'b', 'c'])new_data = data.reindex(['a', 'b', 'c', 'd']) print(new_data)print(new_data.dropna())
  • 扔掉全部都是缺失的数据(NaN)的行
print(new_data.dropna(how='all'))
  • 填充所有缺失数据为一个值
print(new_data.fillna(0))
  • 按列填充缺失数据为不同值「fillna:按列填写缺失值,如果存在着不填。」
dict_data = {    'Student': ['lilei', 'hanmeimei', 'aiyuechuang'],    'Score': [99, 100, 135],    'Gender': ['M', 'F', 'M']}data = pd.DataFrame(dict_data,    columns=['Gender', 'Score', 'Student', 'Age'],    index=['a', 'b', 'c'])new_data = data.reindex(['a', 'b', 'c', 'd'])key_value = {'Gender': 'F', 'Score': 145, 'Student': 'Alex', 'Age': 21}print(new_data.fillna(key_value))#  输入  Gender  Score      Student  Agea      M   99.0        lilei   21b      F  100.0    hanmeimei   21c      M  135.0  aiyuechuang   21d      F  145.0         Alex   21
  • 筛选数据
dict_data = {    'Student': ['lilei', 'hanmeimei', 'aiyuechuang'],    'Score': [80, 100, 135],    'Gender': ['M', 'F', 'M']}data = pd.DataFrame(dict_data,    columns=['Gender', 'Score', 'Student', 'Age'],    index=['a', 'b', 'c'])print(data[data['Score'] >= 90])# 输入  Gender  Score      Student  Ageb      F    100    hanmeimei  NaNc      M    135  aiyuechuang  NaN
  • 从列表中筛选数据
dict_data = {    'Student': ['lilei', 'hanmeimei', 'aiyuechuang', 'Alex', 'Cleland', 'AI悦创'],    'Score': [80, 100, 135, 90, 85, 95],    'Gender': ['M', 'F', 'M', 'M', 'F', 'M']}data = pd.DataFrame(dict_data)select_list = [95, 100, 135]# print(data)print(data[data['Score'].isin(select_list)])
  • GroupBy
import pandas as pdipl_data = {'Team': ['Riders', 'Riders', 'Devils', 'Devils', 'Kings',         'kings', 'Kings', 'Kings', 'Riders', 'Royals', 'Royals', 'Riders'],         'Rank': [1, 2, 2, 3, 3,4 ,1 ,1,2 , 4,1,2],         'Year': [2014,2015,2014,2015,2014,2015,2016,2017,2016,2014,2015,2017],         'Points':[876,789,863,673,741,812,756,788,694,701,804,690]}df = pd.DataFrame(ipl_data)print (df)# 执行下面示例代码,失去以下后果 -    Points  Rank    Team  Year0      876     1  Riders  20141      789     2  Riders  20152      863     2  Devils  20143      673     3  Devils  20154      741     3   Kings  20145      812     4   kings  20156      756     1   Kings  20167      788     1   Kings  20178      694     2  Riders  20169      701     4  Royals  201410     804     1  Royals  201511     690     2  Riders  2017"""将数据拆分成组Pandas对象能够分成任何对象。有多种形式来拆分对象,如 -- obj.groupby(‘key’)- obj.groupby([‘key1’,’key2’])- obj.groupby(key,axis=1)当初来看看如何将分组对象利用于 DataFrame 对象示例"""import pandas as pdipl_data = {'Team': ['Riders', 'Riders', 'Devils', 'Devils', 'Kings',         'kings', 'Kings', 'Kings', 'Riders', 'Royals', 'Royals', 'Riders'],         'Rank': [1, 2, 2, 3, 3,4 ,1 ,1,2 , 4,1,2],         'Year': [2014,2015,2014,2015,2014,2015,2016,2017,2016,2014,2015,2017],         'Points':[876,789,863,673,741,812,756,788,694,701,804,690]}df = pd.DataFrame(ipl_data)print (df.groupby('Team'))# 执行下面示例代码,失去以下后果 -<pandas.core.groupby.DataFrameGroupBy object at 0x00000245D60AD518># 查看分组import pandas as pdipl_data = {'Team': ['Riders', 'Riders', 'Devils', 'Devils', 'Kings',         'kings', 'Kings', 'Kings', 'Riders', 'Royals', 'Royals', 'Riders'],         'Rank': [1, 2, 2, 3, 3,4 ,1 ,1,2 , 4,1,2],         'Year': [2014,2015,2014,2015,2014,2015,2016,2017,2016,2014,2015,2017],           'Points':[876,789,863,673,741,812,756,788,694,701,804,690]}df = pd.DataFrame(ipl_data)print (df.groupby('Team').groups)# 执行下面示例代码,失去以下后果 -{'Devils': Int64Index([2, 3], dtype='int64'), 'Kings': Int64Index([4, 6, 7], dtype='int64'), 'Riders': Int64Index([0, 1, 8, 11], dtype='int64'), 'Royals': Int64Index([9, 10], dtype='int64'), 'kings': Int64Index([5], dtype='int64')}# 失去的后果相似字典的构造,提取字典的值之后,能够间接用整数索引或者应用 .values 能够提取出分组之后的值「数组」
  • 利用 groupby 对数据进行分组并计算 sum, mean 等
import pandas as pddata = pd.DataFrame({    "tag_id": ['a', 'b', 'c', 'a', 'a', 'c', 'c'],    'count': [10, 30, 20, 10, 15, 22, 22]    })grouped_data = data.groupby('tag_id')print(grouped_data.sum())# 输入        counttag_id       a          35b          30c          64
data = pd.DataFrame({    "tag_id": ['a', 'b', 'c', 'a', 'a', 'c', 'c'],    'count': [10, 30, 20, 10, 15, 22, '22']    })grouped_data = data.groupby('tag_id')print(grouped_data.sum())# 输入        counttag_id       a        35.0b        30.0c         NaN
data = pd.DataFrame({    "tag_id": ['a', 'b', 'c', 'a', 'a', 'c', 'c'],    'count': [10, 30, 20, 10, 15, 22, 22]    })grouped_data = data.groupby('count')print(grouped_data.sum())# 输入      tag_idcount       10        aa15         a20         c22        cc30         b
  • 数据排序——按索引名称升序排列
import pandas as pddata = pd.DataFrame({    "tag_id": ['0802', '0823', '0832', '0731'],    'count': [10, 30, 20, 10]    },    index=['b', 'c', 'a', 'd'])print(data)print(data.sort_index())
  • 数据排序——按索引名称降序排列
print(data.sort_index(ascending=False)) # ascending 回升
  • 数据排序——按某一列的数据进行排序
print(data.sort_values(by='tag_id'))
  • 数据汇总「对 DataFrame 的数据全副进行求和」
data = pd.DataFrame({    "tag_id": ['AI', 'YC', 'FP', 'MK'],    'count': [10, 30, 20, 10]    })# print(data)print(data.sum())
  • 一些罕用的办法

    函数阐明
    count计算非 NaN 数据的数量
    min、max计算最小、最大值
    argmin、argmax计算最小、最大值地位
    sum计算数值的和
    mean计算平均数
    median计算中位数
    var计算方差
    std计算标准差
  • 同一个轴能够用多种形式来索引
import numpy as npimport pandas as pdnp_data = np.random.randint(1, 5, size=7)book_ratings = pd.Series(    np_data,     index=[    ['b1', 'b1', 'b2', 'b2', 'b3', 'b4', 'b4'],    [1, 2, 1, 2, 1, 2, 3]    ])print(book_ratings)print(book_ratings.loc['b1'])# 输入b1  1    4    2    3b2  1    4    2    1b3  1    2b4  2    1    3    3dtype: int641    42    3dtype: int64
  • 两个 DataFrame 进行合并
import pandas as pdbook_name = pd.DataFrame({    'book_name': ['a', 'b', 'c', 'd', 'e', 'f'],    'book_id': [11, 22, 33, 44, 55, 66]    })id_rating = pd.DataFrame({    'book_id': [11, 22, 22, 44, 55, 66, 33, 11, 55],    'rating': [1, 3, 5, 2, 4, 3, 2, 4, 5]    })print(pd.merge(book_name, id_rating))

  • 两个 DataFrame 进行合并,不指定连贯形式「默认是把他们都有的」
data1 = pd.DataFrame({    'key': ['a', 'b', 'a', 'c', 'b', 'd'],    'data1': [1, 2, 3, 4, 5, 6]    })data2 = pd.DataFrame({    'key': ['a', 'b', 'c'],    'data2': [8, 9, 7]    })print(pd.merge(data1, data2))

默认把两个数据框都有的数据进行合并。

  • 两个 DataFrame 进行合并,指定连贯形式「当初咱们心愿,你不要把单方都有的留下来,我要把只有一方有的也留下来」
print(pd.merge(data1, data2, how='outer'))
# 输入  key  data1  data20   a      1    8.01   a      3    8.02   b      2    9.03   b      5    9.04   c      4    7.05   d      6    NaN

还能够应用 left、right 「相似交加并集、交加之类的」

  • 两个 DataFrame 进行合并,指定连贯的列名称「两个数据框都有的一个列,来合并」
data1 = pd.DataFrame({    'key': ['a', 'b', 'a', 'c', 'b', 'b'],    'data1': [1, 2, 3, 4, 5, 6]    })data2 = pd.DataFrame({    'key': ['a', 'b', 'c'],    'data2': [8, 9, 7]    })print(pd.merge(data1, data2, on='key'))
  • 两个 DataFrame 进行合并,别离指定连贯的列名称「两个数据没有重合的名称,咱们别离指定列来合并」
print(pd.merge(data1, data2,    left_on='lkey',     right_on='rkey'))
  • Pandas 文件存取——读取 CSV 文件「默认会把文件的第一行,变成题目」https://aiyc.lanzoux.com/iSU8ufj79af
data = pd.read_csv('rating.csv')
  • 读取 CSV 文件,不要题目行「勾销第一行为题目」
data = pd.read_csv('rating.csv', header=None)
  • 读取 CSV 文件,自定义题目行
data = pd.read_csv('rating.csv', names=['user_id', 'book_id', 'rating'])
  • 读取 CSV 文件,指定索引列「有可能我都某一列是咱们的索引列,所以这个时候须要指定索引列」
data = pd.read_csv('rating.csv',                  names=['user_id', 'book_id', 'rating'],                  index_col='user_id')
  • 读取 CSV 文件,指定分隔符
data = pd.read_csv('rating.csv',                  names=['user_id', 'book_id', 'rating'],                  sep=',')
  • 读取 CSV 文件,主动解决缺失的数据「pandas 比拟智能中央就是会把空的中央补上 Nan」

新建 data.csv 文件,外面存储如下数据

1,2,3,4,56,7,8,,1011,,13,14,15

代码如下:

data = pd.read_csv('data.csv', header=None)
  • 贮存数据为 CSV 文件
import pandas as pddata = pd.DataFrame({    'student': ['lilei', 'hanmeimei', 'madongmei'],    'gender': ['M', 'F', 'F'],    'score': [90, 80, 100]    })data.to_csv('student.csv')
,student,gender,score0,lilei,M,901,hanmeimei,F,802,madongmei,F,100

在软件中关上:

  • 读取 Excel 文件,首先装置 xlrd 模块

Windows 零碎:

pip install xlrd

Mac 零碎:

pip3 install xlrd

新建一个 Excel 文件,保留文件名称为:student.xlsx

读取 Excel 文件

import pandas as pdfile = pd.ExcelFile('student.xlsx')data = file.parse('Sheet1') # Excel 表格名称print(data)# 输入   Unnamed: 0    student gender  score0           0      lilei      M     901           1  hanmeimei      F     802           2  madongmei      F    100
  • Pandas VS. Numpy 读取文件速度比拟
import numpy as npimport pandas as pdimport timestart_time = time.time()data = np.genfromtxt('./rating.txt', delimiter=',')end_reading_time = time.time()print('Numpy reading time: {}ms'.format(round((end_reading_time - start_time) * 1000, 2)))start_time = time.time()data = pd.read_table('./rating.csv',     names=['user_id', 'book_id', 'rating'],    sep=',')end_reading_time = time.time()print('Pandas reading time: {}ms'.format(round((end_reading_time - start_time) * 1000, 2)))# 输入Numpy reading time: 27029.64msPandas reading time: 1003.31ms

Pandas 读取速度很快,解决起来比 Numpy 慢一些。Numpy 是最底层的,Pandas 会智能的时候给你做一些数据处理,所以很多时候咱们应用 Pandas 。

剖析热门标签

数据集:https://aiyc.lanzoux.com/iqgPTfxyrxc

  • 工作1:找出最多人想读的 50本书的名称
  • 工作2:找出这 50本书对应最热门的10个标签

文件1:to_read.csv

  • 每行两个数据,用户 id 和该用户想读的书籍 id

文件2:books.csv

  • 书籍的各类 id,名称,作者等信息

文件3:tags.csv

  • 每行两个数据,标签 id 和标签名称

文件4:book_tags.csv

  • 每行三个数据,_goodreads_book_id_(和 to_read 中的书籍 id 的对应关系能够在 books.csv 里找到),标签 id,标记次数

解答

Python 原生的解决形式,代码如下「简版代码」:

import pandas as pdimport numpy as npdata = pd.read_csv('../to_read.csv')# print(data)new_data = data['book_id']# array_lengt = len(set(data['book_id']))# print(array_lengt)# book_count_array = np.zeros(array_lengt)# print(set(new_data))book_id_values = {}result = list(new_data)for data in set(new_data):    book_id_values[data] = result.count(data)# print(book_id_values)d_sorted_by_value = sorted(book_id_values.items(), key=lambda x: x[1]) # 依据字典值的升序排序a = d_sorted_by_value[::-1][:50]print(a)print(len(a))
[(47, 2772), (143, 1967), (113, 1840), (13, 1812), (11, 1767), (45, 1717), (139, 1650), (39, 1619), (65, 1608), (35, 1576), (342, 1521), (185, 1502), (119, 1499), (8, 1498), (6, 1484), (4, 1478), (94, 1460), (89, 1458), (55, 1441), (61, 1435), (109, 1432), (16, 1425), (31, 1417), (67, 1352), (146, 1342), (54, 1339), (46, 1325), (121, 1313), (5, 1293), (173, 1292), (115, 1285), (68, 1257), (36, 1211), (95, 1208), (167, 1188), (129, 1181), (265, 1180), (137, 1172), (277, 1160), (66, 1158), (267, 1154), (268, 1149), (28, 1148), (38, 1130), (60, 1129), (14, 1127), (225, 1111), (10, 1110), (233, 1106), (252, 1105)]50[Finished in 147.9s]

Pandas 代码:

第一步,找到最热的50本书

import pandas as pdimport numpy as npto_read = pd.read_csv('../to_read.csv')to_read_counts = to_read['book_id'].value_counts().sort_values(ascending=False)hottest_50_books_id = to_read_counts[:50].indexhottest_50_books_counts = to_read_counts[:50].valueshottest_50_books = pd.DataFrame({    'book_id': hottest_50_books_id,    'to_read_counts': hottest_50_books_counts    })"""波及到的知识点1. value_counts():     计算反复元素呈现的次数「显示模式为:值为索引,次数为值」2. sort_values():     按某一列的数据进行排序,应用 by=列名,来指定。                     默认是升序排序,能够应用 ascending=False 来反转"""print(hottest_50_books)
    book_id  to_read_counts0        47            27721       143            19672       113            18403        13            18124        11            17675        45            17176       139            16507        39            16198        65            16089        35            157610      342            152111      185            150212      119            149913        8            149814        6            148415        4            147816       94            146017       89            145818       55            144119       61            143520      109            143221       16            142522       31            141723       67            135224      146            134225       54            133926       46            132527      121            131328        5            129329      173            129230      115            128531       68            125732       36            121133       95            120834      167            118835      129            118136      265            118037      137            117238      277            116039       66            115840      267            115441      268            114942       28            114843       38            113044       60            112945       14            112746      225            111147       10            111048      233            110649      252            1105[Finished in 0.6s]

第二步,找到书籍的名称

books = pd.read_csv('../books.csv')book_id_and_title = books[['book_id', 'goodreads_book_id', 'title']]hottest_50_books_with_title = pd.merge(    hottest_50_books,     book_id_and_title,     how='left')print(hottest_50_books_with_title)hottest_50_books_with_title.to_csv('hottest_50_books_with_title.csv')

第三步,找到这50本书对应最热的10个标签

book_tags = pd.read_csv('../book_tags.csv')book_tags = book_tags[book_tags['_goodreads_book_id_'].isin(hottest_50_books_with_title['goodreads_book_id'])]del book_tags['_goodreads_book_id_']hottest_10_tags = book_tags.groupby('tag_id').sum()hottest_10_tags = hottest_10_tags.sort_values(by='count', ascending=False)[:10]hottest_10_tags = pd.DataFrame({    'tag_id': hottest_10_tags.index,    'count': hottest_10_tags['count']    })print(hottest_10_tags['tag_id'])

第四步,找到这10个标签的名称

tags = pd.read_csv('../tags.csv')hottest_10_tags_with_tag_name = pd.merge(    hottest_10_tags,    tags,    on='tag_id',    how='left')print(hottest_10_tags_with_tag_name)hottest_10_tags_with_tag_name.to_csv('hottest_10_tags_with_tag_name.csv')

欢送关注我公众号:AI悦创,有更多更好玩的等你发现!

公众号:AI悦创

AI悦创·推出辅导班啦,包含「Python 语言辅导班、C++ 辅导班、java 辅导班、算法/数据结构辅导班、少儿编程、pygame 游戏开发」,全部都是一对一教学:一对一辅导 + 一对一答疑 + 安排作业 + 我的项目实际等。当然,还有线下线上摄影课程、Photoshop、Premiere 一对一教学、QQ、微信在线,随时响应!微信:Jiabcdefh

办法一:QQ

办法二:微信:Jiabcdefh