pandas 是基于NumPy 的一种工具,该工具是为了解决数据分析任务而创建的。Pandas 纳入了大量库和一些标准的数据模型,提供了高效地操作大型数据集所需的工具。pandas提供了大量能使我们快速便捷地处理数据的函数和方法。你很快就会发现,它是使Python成为强大而高效的数据分析环境的重要因素之一。
pandas is a fast, powerful, flexible and easy to use open source data analysis and manipulation tool,built on top of the Python programming language.
进入官网可以看到现在最新的版本是1.0.3,之后代码也就使用1.0.3的pd咯。此系列主要参考Pandas官方文档和由Datawhale主办的一期Joyful-Pandas,结合自己使用pandas的一些体会进行扩展,最后还有个人对问题和练习的解答。使用到的数据集可以在此下载。
#从清华镜像拉装1.0.3版本的Pandas
!pip install -i https://pypi.tuna.tsinghua.edu.cn/simple pandas==1.0.3
import pandas as pd
#查看Pandas版本
pd.__version__
'1.0.3'
一般使用python安装库,会用到pip install libName。这会在Python的官方源pypi.python.org/pypi 下载,有时会因为超时会抛异常无法下载成功。所以可以选择一些比较稳定速度比较快的国内镜像来下载python库。
这里选择用清华的镜像是因为大多数时候直接pip install 一个库
会比较慢,国内常用阿里、豆瓣、中科大的镜像网址如下,可以自行选择替换。
https://mirrors.aliyun.com/pypi/simple/
https://pypi.douban.com/simple
https://mirrors.ustc.edu.cn/pypi/web/simple
一、csv、txt、xls或xlsx文件读取与写入
1. 读取与写入csv格式
#读取
df = pd.read_csv('work/table.csv')
df.head()#默认查看前五行,想看n行的话就在括号内加数字,如前20行 df.head(20)
#写入
df.to_csv('data/new_table.csv')
#df.to_csv('data/new_table.csv', index=False) #保存时除去行索引
#df.to_csv('data/new_table.csv', header=False) #保存时除去列索引
2. 读取与写入txt格式
#读取
df_txt = pd.read_table('work/table.txt') #可设置sep分隔符参数
#df_txt = pd.read_table('work/table.txt',sep='\t') #其实上行代码就是默认分隔符为\t,即空四个字符
df_txt
#写入
df_txt.to_csv('data/new_table.txt', index=False)
打开写入的‘new_table.txt’,就会发现格式和之前不太一样,使用‘,’分隔。因此读取时可以使用df_txt = pd.read_table('data/new_table.txt',sep=',')
。如果要保持一致,也就是分隔符为\t,那么可以使df_txt.to_csv('data/new_table.txt', index=False,sep='\t')
。
#读取
!pip install -i https://pypi.tuna.tsinghua.edu.cn/simple xlrd
import xlrd
#需要安装xlrd包
df_excel = pd.read_excel('work/table.xlsx')
df_excel.head()
#写入
!pip install -i https://pypi.tuna.tsinghua.edu.cn/simple openpyxl
import openpyxl
#需要安装openpyxl
df.to_excel('data/new_table2.xlsx', sheet_name='Sheet1')
打开写入的‘new_table2.xlsx’,就会发现格式和之前不太一样,因为没有删除行索引。如果要保持一致,那么可以使df.to_excel('data/new_table.xlsx', sheet_name='Sheet1', index=False)
,就可以得到“无添加”。
在pandas中有两类非常重要的数据结构,即序列Series和数据框DataFrame。Series类似于numpy中的一维数组,除了通吃一维数组可用的函数或方法,而且其可通过索引标签的方式获取数据,还具有索引的自动对齐功能;DataFrame类似于numpy中的二维数组,同样可以通用numpy数组的函数和方法,而且还具有其他灵活应用。
1. Series对于一个Series,其中最常用的属性为值(values),索引(index),名字(name),类型(dtype)。访问Series属性就直接一个点+属性名。Series有相当多的方法可以调用,也是就直接一个点+调用方法。下面上代码:
Series创建#创建一个Series,这里是随机的,故得到的结果每次也不一样
s = pd.Series(np.random.randn(5),index=['a','b','c','d','e'],name='这是一个Series',dtype='float64')
s
a -1.871256
b -1.048312
c -1.068401
d 0.168282
e -1.606225
Name: 这是一个Series, dtype: float64
访问Series属性
#访问Series属性
s.values
s.name
s.index
s.dtype
#取Series中某一索引的值
s['a']
Series调用方法
#Series有相当多的方法可以调用,使用方式和属性一样,直接一个点+调用方法
print([attr for attr in dir(s) if not attr.startswith('_')])
print(s.mean())
['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']
-1.0851822894643066
2. DataFrame
数据框DataFrame更为复杂,使用方法也更多了。
DataFrame创建#创建一个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
print(df['col1'],'\n'*2,type(df),'\n'*2,type(df['col1']))
一 a
二 b
三 c
四 d
五 e
Name: col1, dtype: object
从DataFrame取出一列为Series。因此,通过DataFrame中的某一行或某一列也可以创建序列Series。
DataFrame修改行/列名#修改行或列名
df.rename(index={'一':'one'},columns={'col1':'new_col1'})
DataFrame调用属性和方法
#调用属性和方法,与序列Series相同,直接一个点+调用属性/方法
print(df.index,'\n'*2,
df.columns,'\n'*2,
df.values,'\n'*2,
df.shape,'\n'*2,
df.mean()
)
Index(['一', '二', '三', '四', '五'], dtype='object')
Index(['col1', 'col2', 'col3'], dtype='object')
[['a' 5 1.3]
['b' 6 2.5]
['c' 7 3.6]
['d' 8 4.6]
['e' 9 5.8]]
(5, 3)
col2 7.00
col3 3.56
dtype: float64
“索引对齐特性”
“索引对齐特性”是Pandas中非常强大的特性,下面举个例子。
df1 = pd.DataFrame({'A':[1,2,3]})
df2 = pd.DataFrame({'A':[1,2,3]})
df1-df2 #由于索引默认对齐,因此结果是0
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
DataFrame列的删除/增加
列的删除有三种方法,drop函数或del或pop。del会直接在原DataFrame中改动。pop方法直接在原来的DataFrame上操作,且返回被删除的列,与python中的pop函数类似。
df.drop(index='五',columns='col1') #设置inplace=True后会直接在原DataFrame中改动
df#未设置设置inplace=True,原DataFrame中不发生变化
df['col1']=[1,2,3,4,5]
del df['col1']
df#del会直接在原DataFrame中改动
df['col1']=[1,2,3,4,5]
df.pop('col1')
df#pop会直接在原DataFrame中改动
列的增加,可以直接增加新的列,也可以使用assign方法。但assign方法不会对原DataFrame做修改,需要自行保存一下。
df1['B']=list('abc')
df1#直接增加了新的列
df1.assign(C=pd.Series(list('def')))#使用assign方法
df1#但assign方法不会对原DataFrame做修改
df1_new=df1.assign(C=pd.Series(list('def')))#新定义
df1_new
DataFrame根据类型选择列
根据类型选择列,刚才df第一列是字母,第二列是整数,第三列是浮点数。
df.select_dtypes(include=['number']).head()
df.select_dtypes(include=['float']).head()
DataFrame转置
数据框DataFrame使用T符号可以转置。
df1_new.T
Series转换为DataFrame
前面引用所说:Series类似于numpy中的一维数组,DataFrame类似于numpy中的二维数组。因此也可以将Series转换为DataFrame。
s = df.mean()
s.name='S_to_DataFrame'
print(type(s))#
s.to_frame()
三、常用基本函数
head和tail
head和tail可以指定n参数显示多少行,head是从前往后,tail是从后往前。
df = pd.read_csv('work/table.csv')
#df.head(20) #之前有简单说明
df.tail()
unique和nunique
nunique显示有多少个唯一值,unique显示所有的唯一值。
print(df['Physics'].nunique())
print(df['Physics'].unique())
7
['A+' 'B+' 'B-' 'A-' 'B' 'A' 'C']
count和value_counts
count返回非缺失值元素个数,value_counts返回每个元素有多少个(不包括缺失值对应情况)。
print(df['Physics'].count())
print('\n')
print(df['Physics'].value_counts())
35
B+ 9
B 8
B- 6
A 4
A+ 3
A- 3
C 2
Name: Physics, dtype: int64
info和describe
info函数返回有哪些列、有多少非缺失值、每列的类型。
df.info()
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
describe默认统计数值型数据的各个统计量,默认分位数是0.25,0.5,0.75,也可以自行选择分位数percentiles=[.05, .25, .75, .95]
。如果需要统计全部属性数据可以使用df.describe(include='all')
,include= “O“ 则是描述object类型的熟悉, include= ”all“则是对所有属性的描述。
df.describe()
df.describe(include='O')
df['Physics'].describe()#对于非数值型也可以用describe函数
idxmax、idxmin和nlargest、nsmallest
idxmax函数返回最大值,在某些情况下特别适用,idxmin功能相反。
nlargest函数返回前几个大的元素值,nsmallest功能相反。
print("max:",df['Math'].idxmax(),",min:",df['Math'].idxmin())
print('\n')
print(df['Math'].nlargest(3))
print(df['Math'].nsmallest(3))
max: 5 ,min: 10
5 97.0
28 95.5
11 87.7
Name: Math, dtype: float64
10 31.5
1 32.5
26 32.7
Name: Math, dtype: float64
apply函数
apply是一个自由度很高的函数,之后还要提到。与apply相似的还有applymap和map,大多数时候使用map、apply。我理解的apply就是一个映射关系。
apply 用在dataframe上,用于对row或者column进行计算;applymap用于dataframe上,是元素级别的操作;map(python自带)用于series上,是元素级别的操作。
apply对于Series,它可以迭代每一列的值操作:
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
对于DataFrame,它可以迭代每一个列操作,如下最终导致全部加了‘!’:
df.apply(lambda x:x.apply(lambda x:str(x)+'!')).head() #这是一个稍显复杂的例子,有利于理解apply的功能
clip和replace
clip和replace是两类替换函数。clip是对超过或者低于某些值的数进行截断,replace是对某些值进行替换。
print('原来')
print(df['Math'].head())
print('后来')
print(df['Math'].clip(33,80).head())
print('实际上这些函数都没有对原数据处理,需要使用的话进行新定义保持')
print(df['Math'].head())
df['Math']=df['Math'].clip(33,80)
print(df['Math'].head())
原来
0 34.0
1 32.5
2 87.2
3 80.4
4 84.8
Name: Math, dtype: float64
后来
0 34.0
1 33.0
2 80.0
3 80.0
4 80.0
Name: Math, dtype: float64
实际上这些函数都没有对原数据处理,需要使用的话进行新定义保持
0 34.0
1 32.5
2 87.2
3 80.4
4 84.8
Name: Math, dtype: float64
0 34.0
1 33.0
2 80.0
3 80.0
4 80.0
Name: Math, dtype: float64
replace是对某些值进行替换,数据挖掘中常用来做缺省值的替换。下面的例子中自行构造一个缺省,并用中位数填充。
df = pd.read_csv('work/table.csv')
print('原来')
print(df['Address'].head())
print("经过'street_1','street_2'到'one','two'的替换")
print(df['Address'].replace(['street_1','street_2'],['one','two']).head())
print('实际上可以直接在表中修改')
print(df.replace({'Address':{'street_1':'one','street_2':'two'}}).head())
print('这个表没有缺省值,而这个在数据挖掘中常用来做缺省值的替换。下面演示的是将正常的改成缺省后填充中位数:')
df=df.replace({'Math':{34:np.nan}})
print(df.head())
print('缺省后填充中位数',df['Math'].median())
print(df.replace(np.nan,df['Math'].median()).head())
原来
0 street_1
1 street_2
2 street_2
3 street_2
4 street_4
Name: Address, dtype: object
经过'street_1','street_2'到'one','two'的替换
0 one
1 two
2 two
3 two
4 street_4
Name: Address, dtype: object
实际上可以直接在表中修改
School Class ID Gender Address Height Weight Math Physics
0 S_1 C_1 1101 M one 173 63 34.0 A+
1 S_1 C_1 1102 F two 192 73 32.5 B+
2 S_1 C_1 1103 M two 186 82 87.2 B+
3 S_1 C_1 1104 F two 167 81 80.4 B-
4 S_1 C_1 1105 F street_4 159 64 84.8 B+
这个表没有缺省值,而这个在数据挖掘中常用来做缺省值的替换。下面演示的是将正常的改成缺省后填充中位数:
School Class ID Gender Address Height Weight Math Physics
0 S_1 C_1 1101 M street_1 173 63 NaN 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+
缺省后填充中位数 62.6
School Class ID Gender Address Height Weight Math Physics
0 S_1 C_1 1101 M street_1 173 63 62.6 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+
四、排序
索引排序
参数太多了。还是就常用的方式举个例子。更深入的可以看文档。DataFrame.sort_index(self, axis=0, level=None, ascending=True, inplace=False, kind='quicksort', na_position='last', sort_remaining=True, ignore_index: bool = False)
sort_index函数官方文档说明
df = pd.read_csv('work/table.csv')
print(df.set_index('Math').head())#set_index函数可以设置索引,将在之后详细介绍
print('默认ascending=True正序')
print(df.set_index('Math').sort_index().head())
print('倒序')
print(df.set_index('Math').sort_index(ascending=False).head())
School Class ID Gender Address Height Weight Physics
Math
34.0 S_1 C_1 1101 M street_1 173 63 A+
32.5 S_1 C_1 1102 F street_2 192 73 B+
87.2 S_1 C_1 1103 M street_2 186 82 B+
80.4 S_1 C_1 1104 F street_2 167 81 B-
84.8 S_1 C_1 1105 F street_4 159 64 B+
默认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+
倒序
School Class ID Gender Address Height Weight Physics
Math
97.0 S_1 C_2 1201 M street_5 188 68 A-
95.5 S_2 C_3 2304 F street_6 164 81 A-
87.7 S_1 C_3 1302 F street_1 175 57 A-
87.2 S_1 C_1 1103 M street_2 186 82 B+
85.4 S_2 C_2 2205 F street_7 183 76 B
值排序
参数太多了。还是就举常用的例子。更深入的可以看文档。DataFrame.sort_values(self, by, axis=0, ascending=True, inplace=False, kind='quicksort', na_position='last', ignore_index=False)
sort_values函数官方文档说明
print(df.sort_values(by='Class').head())
print('多个值排序,即先对第一层排,在第一层相同的情况下对第二层排序')
print(df.sort_values(by=['Class','Height']).head())
School Class ID Gender Address Height Weight Math Physics
0 S_1 C_1 1101 M street_1 173 63 34.0 A+
19 S_2 C_1 2105 M street_4 170 81 34.2 A
18 S_2 C_1 2104 F street_5 159 97 72.2 B+
16 S_2 C_1 2102 F street_6 161 61 50.6 B+
15 S_2 C_1 2101 M street_7 174 84 83.3 C
多个值排序,即先对第一层排,在第一层相同的情况下对第二层排序
School Class ID Gender Address Height Weight Math Physics
17 S_2 C_1 2103 M street_4 157 61 52.5 B-
4 S_1 C_1 1105 F street_4 159 64 84.8 B+
18 S_2 C_1 2104 F street_5 159 97 72.2 B+
16 S_2 C_1 2102 F street_6 161 61 50.6 B+
3 S_1 C_1 1104 F street_2 167 81 80.4 B-
五、问题与练习(附解答)
【问题一】 Series和DataFrame有哪些常见属性和方法?
属性和方法都有很多,尤其是方法太多太多了。一般只要熟悉常用的几个就可以了。哪些是常用的?上文提到的就是常用。
https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.Series.html#pandas.Series
https://pandas.pydata.org/pandas-docs/stable/reference/frame.html
【问题二】 value_counts会统计缺失值吗?
如上文中提到的,
count返回非缺失值元素个数,value_counts返回每个元素有多少个(不包括缺失值对应情况)。
df = pd.read_csv('work/table.csv')
print('原来')
print(df['Math'].head())
print('这个表没有缺省值,下面演示的是将正常的改成缺省后')
df=df.replace({'Math':{34:np.nan}})
print(df.head())
print('Math有一个缺省值')
print(df.isnull().sum())
print('下面这个方法花哨一些,value_counts统计了"-"代替的缺省值')
df['Math'].replace(np.nan, '-', inplace=True)#inplace=True,表示在原数据表修改了
df['Math'].value_counts()
原来
0 34.0
1 32.5
2 87.2
3 80.4
4 84.8
Name: Math, dtype: float64
这个表没有缺省值,下面演示的是将正常的改成缺省后
School Class ID Gender Address Height Weight Math Physics
0 S_1 C_1 1101 M street_1 173 63 NaN 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+
Math有一个缺省值
School 0
Class 0
ID 0
Gender 0
Address 0
Height 0
Weight 0
Math 1
Physics 0
dtype: int64
下面这个方法花哨一些,value_counts统计了"-"代替的缺省值
63.5 1
72.3 1
45.3 1
87.2 1
85.2 1
84.8 1
83.3 1
95.5 1
80.4 1
32.5 1
- 1
87.7 1
73.8 1
72.2 1
68.4 1
67.7 1
31.5 1
97.0 1
61.7 1
49.7 1
59.7 1
58.8 1
85.4 1
48.7 1
52.5 1
50.6 1
48.9 1
34.2 1
47.2 1
33.8 1
68.5 1
47.6 1
39.1 1
32.7 1
65.9 1
Name: Math, dtype: int64
【问题三】 与idxmax和nlargest功能相反的是哪两组函数?
如上文中提到的,
idxmax函数返回最大值,idxmin功能相反。
nlargest函数返回前几个大的元素值,nsmallest功能相反。
【问题四】 在常用函数一节中,由于一些函数的功能比较简单,因此没有列入,现在将它们列在下面,请分别说明它们的用途并尝试使用。
sum/mean/median/mad/min/max/abs/std/var/quantile/cummax/cumsum/cumprod
sum/mean/median/mad/min/max/abs/std/var/quantile均是最基础的统计量,就不多说了。
cummax=/cumsum/cumprod分别是累计最大值/累计和/累计积。
df = pd.DataFrame([[2.0, 1.0, 1.0],
[2.0, 1.0, 3.0],
[3.0, np.nan, 2.0],
[1.0, 0.0, 1.0]],
columns=list('ABC'))
print(df)
print("默认求'列'的累计最大,且忽略不能计算的(缺省)")
print(df.cummax())
print("axis=1求'行',skipna=False有不能计算的值,直接返回NaN")
print(df.cummax(axis=1,skipna=False))
A B C
0 2.0 1.0 1.0
1 2.0 1.0 3.0
2 3.0 NaN 2.0
3 1.0 0.0 1.0
默认求'列'的累计最大,且忽略不能计算的(缺省)
A B C
0 2.0 1.0 1.0
1 2.0 1.0 3.0
2 3.0 NaN 3.0
3 3.0 1.0 3.0
axis=1求'行',skipna=False有不能计算的值,直接返回NaN
A B C
0 2.0 2.0 2.0
1 2.0 2.0 3.0
2 3.0 NaN NaN
3 1.0 1.0 1.0
【问题五】 df.mean(axis=1)是什么意思?它与df.mean()的结果一样吗?第一问提到的函数也有axis参数吗?怎么使用?
如上一题回答中提到的,axis=1'行',默认'列'。因此结果不同。axis参数的使用也可以参考上一题的回答。
练习涉及到的数据集就在开头说的在此下载中。
【练习一】 现有一份关于美剧《权力的游戏》剧本的数据集'Game_of_Thrones_Script.csv'
,请解决以下问题:
(a)在所有的数据中,一共出现了多少人物?
(b)以单元格计数(即简单把一个单元格视作一句),谁说了最多的话?
(c)以单词计数,谁说了最多的单词?
ex1=pd.read_csv('work/Game_of_Thrones_Script.csv')
print(ex1.columns)
print(ex1)
print('(a)在所有的数据中,一共出现了多少人物?')
print(ex1['Name'].nunique())
print('(b)以单元格计数(即简单把一个单元格视作一句),谁说了最多的话?')
print(ex1['Name'].value_counts().index[0])#value_counts()默认排序从大到小
print('(c)以单词计数,谁说了最多的单词?')
#计算每一句话的单词数
ex1['num_words']=ex1['Sentence'].apply(lambda x:len(x.split(' ')))
#建立'Name'与单词总数对应字典
dict={}
for i in ex1['Name']:
dict[i]=ex1[ex1['Name']==i]['num_words'].sum()
max_value = max(dict.values())
#不能避免有多个相同最大值,所以要遍历
max_list = []
for m, n in dict.items():
if n == max_value:
max_list.append(m)
print(" ".join(max_list))
(a)在所有的数据中,一共出现了多少人物?
564
(b)以单元格计数(即简单把一个单元格视作一句),谁说了最多的话?
tyrion lannister
(c)以单词计数,谁说了最多的单词?
tyrion lannister
【练习二】现有一份关于科比的投篮数据集'Kobe_data.csv'
,请解决如下问题:
(a)哪种action_type和combined_shot_type的组合是最多的?
(b)在所有被记录的game_id中,遭遇到最多的opponent是一个支?
ex2=pd.read_csv('work/Kobe_data.csv')
print(ex2)
print(ex2.columns)
print('(a)哪种action_type和combined_shot_type的组合是最多的?')
ex2['action_type+combined_shot_type']=ex2['action_type']+'***'+ex2['combined_shot_type']
print("和".join(ex2['action_type+combined_shot_type'].value_counts().index[0].split('***')))
print('(b)在所有被记录的game_id中,遭遇到最多的opponent是一个支?')
#建立'game_id'和'opponent'对应字典
dict={}
for i in ex2['game_id']:
dict[i]=ex2[ex2['game_id']==i]['opponent'].unique()
print(pd.DataFrame(dict.values())[0].value_counts().index[0])
(a)哪种action_type和combined_shot_type的组合是最多的?
Jump Shot和Jump Shot
(b)在所有被记录的game_id中,遭遇到最多的opponent是一个支?
SAS
Reference
pandas官网
Joyful-Pandas
python 常用的几个镜像仓库
python里的apply,applymap和map的区别
pandas的DataFrame文档