Pandas基础知识入门

Pandas是基于Numpy构建的含有更高级数据结构和工具的数据分析包。类似于Numpy的核心是ndarray,pandas 也是围绕着 Series 和 DataFrame两个核心数据结构展开的。Series 和 DataFrame 分别对应于一维的序列和二维的表结构。
在这里插入图片描述

Pandas官方教程User Guide ,查看当前版本:

>>> import pandas as pd
>>> import numpy as np
>>> print(pd.__version__)
1.0.1

文件读取与写入

1、文件读取

>>> df = pd.read_csv('data/table.csv') # csv格式
>>> df_txt = pd.read_table('data/table.txt') # txt格式
>>> df_excel = pd.read_excel('data/table.xlsx') #xls或xlsx格式,需要安装xlrd包

2、写入文件

>>> df.to_csv('data/new_table.csv') # csv格式
>>> df.to_csv('data/new_table.csv', index=False) # 保存时除去行索引
>>> df.to_excel('data/new_table2.xlsx', sheet_name='Sheet1') # xls或xlsx格式,需要安装openpyxl

基本数据结构

1、Series

一种类似于一维数组的对象,是由一组数据(各种NumPy数据类型)以及一组与之相关的数据标签(即索引)组成。仅由一组数据也可产生简单的Series对象。注意:Series中的索引值是可以重复的。

A. 创建Series
对于一个Series,其中最常用的属性为值(values),索引(index),名字(name),类型(dtype)。

>>> s = pd.Series(np.random.randn(5),index=['a','b','c','d','e'],name='Series Sample',dtype='float64')
>>> print(s)
a   -0.509401
b   -0.684058
c   -0.759703
d    0.089692
e   -0.114861
Name: Series Sample, dtype: float64

B. 访问Series属性

>>> s.values
array([-0.50940132, -0.68405815, -0.75970341,  0.08969204, -0.11486061])
>>> s.index
Index(['a', 'b', 'c', 'd', 'e'], dtype='object')
>>> s.name
'Series Sample'
>>> s.dtype
dtype('float64')

C. 索引元素

>>> s['a']
-0.5094013170899359

D. 调用方法
Series有相当多的方法可以调用:

>>> print([attr for attr in dir(s) if not attr.startswith('_')])
['T', 'a', 'abs', 'add', 'add_prefix', 'add_suffix', 'agg', 'aggregate', 'align', 'all', 'any', 'append', 'apply', 'argmax', 'argmin', 'argsort', 'array', 'asfreq', 'asof', 'astype', 'at', 'at_time', 'attrs', 'autocorr', 'axes', 'b', 'between', 'between_time', 'bfill', 'bool', 'c', 'clip', 'combine', 'combine_first', 'convert_dtypes', 'copy', 'corr', 'count', 'cov', 'cummax', 'cummin', 'cumprod', 'cumsum', 'd', 'describe', 'diff', 'div', 'divide', 'divmod', 'dot', 'drop', 'drop_duplicates', 'droplevel', 'dropna', 'dtype', 'dtypes', 'duplicated', 'e', 'empty', 'eq', 'equals', 'ewm', 'expanding', 'explode', 'factorize', 'ffill', 'fillna', 'filter', 'first', 'first_valid_index', 'floordiv', 'ge', 'get', 'groupby', 'gt', 'hasnans', 'head', 'hist', 'iat', 'idxmax', 'idxmin', 'iloc', 'index', 'infer_objects', 'interpolate', 'is_monotonic', 'is_monotonic_decreasing', 'is_monotonic_increasing', 'is_unique', 'isin', 'isna', 'isnull', 'item', 'items', 'iteritems', 'keys', 'kurt', 'kurtosis', 'last', 'last_valid_index', 'le', 'loc', 'lt', 'mad', 'map', 'mask', 'max', 'mean', 'median', 'memory_usage', 'min', 'mod', 'mode', 'mul', 'multiply', 'name', 'nbytes', 'ndim', 'ne', 'nlargest', 'notna', 'notnull', 'nsmallest', 'nunique', 'pct_change', 'pipe', 'plot', 'pop', 'pow', 'prod', 'product', 'quantile', 'radd', 'rank', 'ravel', 'rdiv', 'rdivmod', 'reindex', 'reindex_like', 'rename', 'rename_axis', 'reorder_levels', 'repeat', 'replace', 'resample', 'reset_index', 'rfloordiv', 'rmod', 'rmul', 'rolling', 'round', 'rpow', 'rsub', 'rtruediv', 'sample', 'searchsorted', 'sem', 'set_axis', 'shape', 'shift', 'size', 'skew', 'slice_shift', 'sort_index', 'sort_values', 'squeeze', 'std', 'sub', 'subtract', 'sum', 'swapaxes', 'swaplevel', 'tail', 'take', 'to_clipboard', 'to_csv', 'to_dict', 'to_excel', 'to_frame', 'to_hdf', 'to_json', 'to_latex', 'to_list', 'to_markdown', 'to_numpy', 'to_period', 'to_pickle', 'to_sql', 'to_string', 'to_timestamp', 'to_xarray', 'transform', 'transpose', 'truediv', 'truncate', 'tshift', 'tz_convert', 'tz_localize', 'unique', 'unstack', 'update', 'value_counts', 'values', 'var', 'view', 'where', 'xs']
>>> s.mean()
-0.3956662892383938

2、DataFrame

一个表格型的数据结构,包含有一组有序的列,每列可以是不同的值类型(数值、字符串、布尔型等),DataFrame即有行索引也有列索引,可以被看做是由Series组成的字典。

A. 创建DataFrame

>>> df = pd.DataFrame({'col1':list('abcde'),'col2':range(5,10),'col3':[1.3,2.5,3.6,4.6,5.8]},
                 index=list('一二三四五'))
>>> df
   col1  col2  col3
一    a     5   1.3
二    b     6   2.5
三    c     7   3.6
四    d     8   4.6
五    e     9   5.8

B. 从DataFrame取出一列为Series

>>> df['col1']
一    a
二    b
三    c
四    d
五    e
Name: col1, dtype: object
>>> type(df)
pandas.core.frame.DataFrame
>>> type(df['col1'])
pandas.core.series.Series

C. 修改行或列名

>>> df.rename(index={'一':'one'},columns={'col1':'new_col1'})
 new_col1  col2  col3
one        a     5   1.3
二          b     6   2.5
三          c     7   3.6
四          d     8   4.6
五          e     9   5.8

D. 调用属性和方法

>>> df.index
Index(['一', '二', '三', '四', '五'], dtype='object')
>>> df.columns
Index(['col1', 'col2', 'col3'], dtype='object')
>>> df.values
array([['a', 5, 1.3],
       ['b', 6, 2.5],
       ['c', 7, 3.6],
       ['d', 8, 4.6],
       ['e', 9, 5.8]], dtype=object)
>>> df.shape  
(5, 3)
>>> df.mean() #本质上是一种Aggregation操作
col2    7.00
col3    3.56
dtype: float64 

E. 索引对齐特性
这是Pandas中非常强大的特性,不理解这一特性有时就会造成一些麻烦。

>>> df1 = pd.DataFrame({'A':[1,2,3]},index=[1,2,3])
>>> df2 = pd.DataFrame({'A':[1,2,3]},index=[3,1,2])
>>> df1-df2 #由于索引对齐,因此结果不是0
   A
1 -1
2 -1
3  2

F. 列的删除与添加
对于删除而言,可以使用drop函数或del或pop。

>>> df.drop(index='五',columns='col1') #设置inplace=True后会直接在原DataFrame中改动
    col2  col3
一     5   1.36   2.57   3.68   4.6
>>> df['col1']=[1,2,3,4,5] #增加col1列
>>> del df['col2']
>>> df
    col3  col1
一   1.3     12.5     23.6     34.6     45.8     5

pop方法直接在原来的DataFrame上操作,且返回被删除的列,与python中的pop函数类似。

>>> df['col1']=[1,2,3,4,5]
>>> df.pop('col1')12345
Name: col1, dtype: int64
>>> df
    col2  col3
一     5   1.36   2.57   3.68   4.69   5.8

可以直接增加新的列,也可以使用assign方法。

>>> df1['B']=list('abc')
>>> df1
   A  B
1  1  a
2  2  b
3  3  c
>>> df1.assign(C=pd.Series(list('def'))) # 索引对齐
   A  B    C
1  1  a    e
2  2  b    f
3  3  c  NaN
# 但assign方法不会对原DataFrame做修改
>>> df1
   A  B
1  1  a
2  2  b
3  3  c

G. 根据类型选择列

>>> df.select_dtypes(include=['number']).head()
    col2  col3
一     5   1.36   2.57   3.68   4.69   5.8
>>> df.select_dtypes(include=['float']).head()
   col3
一   1.32.53.64.65.8

H. 将Series转换为DataFrame

>>> s = df.mean()
>>> s.name='to_DataFrame'
>>> s # pandas.core.series.Series
col2    7.00
col3    3.56
Name: to_DataFrame, dtype: float64
>>> s.to_frame()
          to_DataFrame
col2          7.00
col3          3.56
>>> s.to_frame().T # 使用T符号可以转置
              col2  col3
to_DataFrame   7.0  3.56

常用基本函数

df = pd.read_csv('data/table.csv')

1. head和tail

>>> df.head()  # 显示前几行
>>> df.tail()  # 显示后几行
>>> df.head(3).append(df.tail(3))
   School  Class  ID    Gender Address   Height   Weight  Math Physics
0     S_1   C_1  1101      M  street_1     173      63  34.0      A+
1     S_1   C_1  1102      F  street_2     192      73  32.5      B+
2     S_1   C_1  1103      M  street_2     186      82  87.2      B+
32    S_2   C_4  2403      F  street_6     158      60  59.7      B+
33    S_2   C_4  2404      F  street_2     160      84  67.7      B
34    S_2   C_4  2405      F  street_6     193      54  47.6      B

2. unique和nunique

# nunique显示有多少个唯一值。
>>> df['Physics'].nunique()
7
# unique显示所有的唯一值
>>> df['Physics'].unique()
array(['A+', 'B+', 'B-', 'A-', 'B', 'A', 'C'], dtype=object)

3. count和value_counts

# count返回非缺失值元素个数
>>> df['Physics'].count()
35
# value_counts返回每个元素有多少个
>>> df['Physics'].value_counts()
B+    9
B     8
B-    6
A     4
A+    3
A-    3
C     2
Name: Physics, dtype: int64

4. describe和info

# describe默认统计数值型数据的各个统计量
>>> df.describe()
               ID      Height      Weight       Math
count    35.00000   35.000000   35.000000  35.000000
mean   1803.00000  174.142857   74.657143  61.351429
std     536.87741   13.541098   12.895377  19.915164
min    1101.00000  155.000000   53.000000  31.500000
25%    1204.50000  161.000000   63.000000  47.400000
50%    2103.00000  173.000000   74.000000  61.700000
75%    2301.50000  187.500000   82.000000  77.100000
max    2405.00000  195.000000  100.000000  97.000000
# 可以自行选择分位数
>>> df.describe(percentiles=[.05, .25, .75, .95])
# 对于非数值型也可以用describe函数
>>> df['Physics'].describe()
count     35
unique     7
top       B+
freq       9
Name: Physics, dtype: object

info函数返回有哪些列、有多少非缺失值、每列的类型。

>>> df.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 35 entries, 0 to 34
Data columns (total 9 columns):
 #   Column   Non-Null Count  Dtype  
---  ------   --------------  -----  
 0   School   35 non-null     object 
 1   Class    35 non-null     object 
 2   ID       35 non-null     int64  
 3   Gender   35 non-null     object 
 4   Address  35 non-null     object 
 5   Height   35 non-null     int64  
 6   Weight   35 non-null     int64  
 7   Math     35 non-null     float64
 8   Physics  35 non-null     object 
dtypes: float64(1), int64(3), object(5)
memory usage: 2.6+ KB

5. idxmax和nlargest

# idxmax函数返回最大值的索引,在某些情况下特别适用,idxmin功能类似
>>> df['Math'].idxmax()
5
# nlargest函数返回前几个大的元素值,nsmallest功能类似
>>> df['Math'].nlargest(3)
5     97.0
28    95.5
11    87.7
Name: Math, dtype: float64

6. clip和replace
clip和replace是两类替换函数,clip是对超过或者低于某些值的数进行截断。

>>> df['Math'].head()
0    34.0
1    32.5
2    87.2
3    80.4
4    84.8
Name: Math, dtype: float64
>>> df['Math'].clip(33,80).head()
0    34.0
1    33.0
2    80.0
3    80.0
4    80.0
Name: Math, dtype: float64

replace是对某些值进行替换。

>>> df['Address'].head()
0    street_1
1    street_2
2    street_2
3    street_2
4    street_4
Name: Address, dtype: object
>>> df['Address'].replace(['street_1','street_2'],['one','two']).head()
0         one
1         two
2         two
3         two
4    street_4
Name: Address, dtype: object
# 通过字典,可以直接在表中修改
>>> df.replace({'Address':{'street_1':'one','street_2':'two'}}).head()

7. apply函数
apply是一个自由度很高的函数,对于Series,它可以迭代每一列的值操作。对于DataFrame,它可以迭代每一个列操作:

>>> df['Math'].apply(lambda x:str(x)+'!').head() #可以使用lambda表达式,也可以使用函数
0    34.0!
1    32.5!
2    87.2!
3    80.4!
4    84.8!
Name: Math, dtype: object
>>> df.apply(lambda x:x.apply(lambda x:str(x)+'!')).head() #这是一个稍显复杂的例子,有利于理解apply的功能
  School  Class  ID     Gender Address   Height Weight Math     Physics
0   S_1!  C_1!  1101!     M!  street_1!   173!    63!  34.0!     A+!
1   S_1!  C_1!  1102!     F!  street_2!   192!    73!  32.5!     B+!
2   S_1!  C_1!  1103!     M!  street_2!   186!    82!  87.2!     B+!
3   S_1!  C_1!  1104!     F!  street_2!   167!    81!  80.4!     B-!
4   S_1!  C_1!  1105!     F!  street_4!   159!    64!  84.8!     B+!

排序

A. 索引排序

>>> df.set_index('Math').head() #set_index函数可以设置索引
>>> df.set_index('Math').sort_index().head() #可以设置ascending参数,默认为升序,True
      School Class  ID    Gender Address    Height  Weight Physics
Math                                                            
31.5    S_1   C_3  1301      M  street_4     161      68      B+
32.5    S_1   C_1  1102      F  street_2     192      73      B+
32.7    S_2   C_3  2302      M  street_5     171      88      A
33.8    S_1   C_2  1204      F  street_5     162      63      B
34.0    S_1   C_1  1101      M  street_1     173      63      A+

B. 值排序

>>> df.sort_values(by='Class').head()
# 多个值排序,即先对第一层排,在第一层相同的情况下对第二层排序
>>> df.sort_values(by=['Address','Height']).head()

问题与练习

1. 问题

【问题一】 Series和DataFrame有哪些常见属性和方法?
【问题二】 value_counts会统计缺失值吗?
【问题三】 与idxmax和nlargest功能相反的是哪两组函数?
【问题四】 在常用函数一节中,由于一些函数的功能比较简单,因此没有列入,现在将它们列在下面,请分别说明它们的用途并尝试使用。 sum/mean/median/mad/min/max/abs/std/var/quantile/cummax/cumsum/cumprod
【问题五】 df.mean(axis=1)是什么意思?它与df.mean()的结果一样吗?第一问提到的函数也有axis参数吗?怎么使用?

2. 练习

【练习一】 现有一份关于美剧《权力的游戏》剧本的数据集,请解决以下问题:
(a)在所有的数据中,一共出现了多少人物?
(b)以单元格计数(即简单把一个单元格视作一句),谁说了最多的话?
(c)以单词计数,谁说了最多的单词?
在这里插入图片描述

# 参考答案
# 问题a
>>> pd.read_csv('data/Game_of_Thrones_Script.csv').head()
>>> df["Name"].nunique()  # 564
# 问题b
>>> df.groupby("Name")["words"].sum().idxmax()
'tyrion lannister'
# 问题c
>>> df = df.assign(words = df["Sentence"].apply(lambda x:len(x.split()))).sort_values(by="Name")  
>>> df.assign(Words = df["Sentence"].apply(lambda x:len(x.split()))).groupby("Name")["words"].sum().idxmax()
'tyrion lannister'

【练习二】现有一份关于科比的投篮数据集,请解决如下问题:
(a)哪种action_type和combined_shot_type的组合是最多的?
(b)在所有被记录的game_id中,遭遇到最多的opponent是一个支?

>>> df = pd.read_csv('data/Kobe_data.csv',index_col='shot_id')
>>> df.head()

在这里插入图片描述

# 问题a
>>> df = df[["action_type","combined_shot_type"]]
>>> df.groupby("action_type")["combined_shot_type"].value_counts().sort_values(ascending=False)
action_type                         combined_shot_type
Jump Shot                           Jump Shot             18880
Layup Shot                          Layup                  2567
Driving Layup Shot                  Layup                  1978
Turnaround Jump Shot                Jump Shot              1057
Fadeaway Jump Shot                  Jump Shot              1048
Running Jump Shot                   Jump Shot               926
Pullup Jump shot                    Jump Shot               476

# 问题b
>>> df =  pd.read_csv('data/Kobe_data.csv',index_col='shot_id').iloc[:,[3,-1]]
>>> pd.Series(list(list(zip(*(pd.Series(list(zip(df["game_id"],df["opponent"]))).unique()).tolist()))[1])).value_counts().index[0]
'SAS'

参考:https://github.com/datawhalechina/joyful-pandas

关于Datawhale

Datawhale是一个专注于数据科学与AI领域的开源组织,汇集了众多领域院校和知名企业的优秀学习者,聚合了一群有开源精神和探索精神的团队成员。Datawhale以“for the learner,和学习者一起成长”为愿景,鼓励真实地展现自我、开放包容、互信互助、敢于试错和勇于担当。同时Datawhale 用开源的理念去探索开源内容、开源学习和开源方案,赋能人才培养,助力人才成长,建立起人与人,人与知识,人与企业和人与未来的联结。

发布了17 篇原创文章 · 获赞 30 · 访问量 1567

猜你喜欢

转载自blog.csdn.net/OuDiShenmiss/article/details/105639227
今日推荐