[TOC]
数据初始化 1、readcsv 1 df = pd.read_csv('file_path' )
2、 1 2 3 4 5 df = pd.DataFrame(columns=['index' , 'v2' ]) df['index' ] = np.arange(10 ) df['v2' ] = np.random.randn(10 ) df.loc[df.index==1 , 'c' ] = '9'
3、pd 和np转换 首先导入numpy模块、pandas模块、创建一个DataFrame类型数据df
1 2 3 4 5 6 7 8 9 10 11 12 13 import numpy as npimport pandas as pddf=pd.DataFrame({'A' :[1 ,2 ,3 ],'B' :[4 ,5 ,6 ],'C' :[7 ,8 ,9 ]}) 1. 使用DataFrame中的values方法df.values 2. 使用DataFrame中的as_matrix()方法df.as_matrix() 3. 使用Numpy中的array方法np.array(df)
语法
操作
返回结果
df.head(n)
查看 DataFrame 对象的前n行
DataFrame
df.tail(n)
查看 DataFrame 对象的最后n行
DataFrame
df.sample(n)
查看 n 个样本,随机
DataFrame
读取列 以下两种方法都可以代表一列:
1 2 3 4 5 df['name' ] df.name df.Q1
注意,当列名为一个合法的 python 变量时可以直接作为属性去使用。
读取部分行列 有时我们需要按条件选择部分列、部分行,一般常用的有:
操作
语法
返回结果
选择列
df[col]
Series
按索引选择行
df.loc[label]
Series
按数字索引选择行
df.iloc[loc]
Series
使用切片选择行
df[5:10]
DataFrame
用表达式筛选行
df[bool_vec]
DataFrame
以上操作称为 Fancy Indexing(花式索引),它来自 Numpy,是指传递一个索引序列,然后一次性得到多个索引元素。Fancy Indexing 和 slicing 不同,它通常将元素拷贝到新的数据对象中。索引中可以有切片 slice,或者省略 ellipsis、新轴 newaxis、布尔数组或者整数数组索引等,可以看做是一个多维切片。
接下来我们将重点介绍一下这些查询的方法。
数据遍历 1. 使用 .iterrows()
iterrows()
方法返回 DataFrame 的索引标签和相应的行数据。这是一个迭代器,它会产生 (index, Series) 对,其中索引是行索引(如果有),Series 是该行的数据。
1 2 3 4 5 6 7 8 9 10 11 import pandas as pddata = {'A' : [1 , 2 , 3 ], 'B' : [4 , 5 , 6 ]} df = pd.DataFrame(data) for index, row in df.iterrows(): print (f"Index: {index} " ) print (f"Row data: {row} " ) print ()
2. 使用 .itertuples()
itertuples()
方法返回一个迭代器,用于迭代 DataFrame 行作为命名元组。这种方式比使用 iterrows()
更快一些,因为不需要创建 Series 对象。
1 2 3 4 5 for row in df.itertuples(index=True , name='Pandas' ): print (f"Index: {row.Index} " ) print (f"Data: A={row.A} , B={row.B} " ) print ()
3. 使用 .apply()
apply()
方法可以应用于整个 DataFrame 或者沿着一个轴应用到每一列或每一行上。这里我们使用 axis=1
来对每一行应用函数。
1 2 3 4 def process_row (row ): print (f"Processing row: {row} " ) df.apply(process_row, axis=1 )
4. 使用 .loc
或 .iloc
如果你想要更灵活地访问特定行或列的数据,可以使用 .loc
或 .iloc
方法。
1 2 3 4 5 6 7 8 9 10 for index in df.index: print (f"Index: {index} " ) print (f"Row data: {df.loc[index]} " ) print () for i in range (len (df)): print (f"Row {i} data: {df.iloc[i]} " ) print ()
切片 [行/列] 我们可以像列表那样利用切片功能选择部分行的数据,但是不支持索引一条:
1 2 3 4 5 df[:2] # 前两行数据 df[4:10] df[:] # 所有数据,一般没这么用的 df[:10:2] # 按步长取 s[::-1] # 反转顺序
也可以选择列:
1 2 3 df['name'] # 只要一列,Series df[['Q1', 'Q2']] # 选择两列 df[['name']] # 选择一列,返回 DataFrame,注意和上例区别
按标签 .loc(行) df.loc()
的格式为 df.loc[<索引表达式>, <列表达式>],表达式支持以下形式:
单个标签:
单个列表标签:
1 2 3 4 5 name, value, socre, grade Eli,9,23,C Ben,8,89,A Tom,7,65,B Toni,6,34,C
1 2 3 4 5 6 df.loc[[0 ,5 ,10 ]] df.loc[['Eli' , 'Ben' ]] df.loc[['Eli' , 'Ben' ],["name" , "grade" ]] df.loc[:,["name" , "grade" ]] df.loc[[False , True ]*50 ]
带标签的切片,包括起始和停止start:stop
, 可以其中只有一个,返回包括它们的数据:
1 2 3 4 df.loc[0 :5 ] df.loc['2010' :'2014' ] df.loc[:]
关于 loc 的更详细介绍可访问:loc 查询数据行和列 。
进行切片操作,索引必须经过排序,意味着索引单调递增或者单调递减,以下代码中其中一个为 True,否则会引发 KeyError
错误。
1 2 3 4 5 6 ( df.index.is_monotonic_increasing, df.index.is_monotonic_decreasing )
通过上边的规则可以先对索引排序再执行词义上的查询,如:
1 2 3 4 5 6 7 8 df.set_index('name' ).sort_index().loc['Ad' :'Bo' ] df.set_index('name' ).sort_index().loc[:'Bo' ] df.set_index('team' ).sort_index().loc['C' : 'D' ] df.sort_values('name' ).set_index('name' ).loc['Te' : 'X' ]
列筛选,必须有行元素:
1 2 3 dft.loc[:, ['Q1' , 'Q2' ]] dft.loc[:, ['Q1' , 'Q2' ]] dft.loc[:10 , 'Q1' :]
按位置 .iloc df.iloc
与 df.loc
相似,但只能用自然索引(行和列的 0 - n 索引),不能用标签。
1 2 3 4 5 df.iloc[:3] df.iloc[:] df.iloc[:, [1, 2]] df.iloc[2:20:3] s.iloc[:3]
如果想筛选多个不连续的行列数据(使用 np.r_
),可以使用以下方法:
1 2 3 4 5 # 筛选索引0-4&10&5-29每两行取一个&70-74 df.iloc[np.r_[:5, 10, 15:30:2, 70:75]] # 行 df.iloc[:, np.r_[0, 2:6]] # 列,0列和第2-5列 # 也可以使用追加的方式拼接 df.loc[:5].append(df.loc[10]).append(df.loc[15:30:2])
关于 iloc 的更详细介绍可访问:iloc 数字索引位置选择 。
取具体值 .at 类似于 loc, 但仅取一个具体的值,结构为 at[<索引>,<列名>]:
1 2 3 4 5 6 7 8 9 10 df.at[4 , 'Q1' ] df.at['lily' , 'Q1' ] df.at[0 , 'name' ] df.loc[0 ].at['name' ] df.set_index('name' ).at['Eorge' , 'team' ] df.set_index('name' ).team.at['Eorge' ] df.team.at[3 ]
同样 iat 和 iloc 一样,仅支持数字索引:
1 2 df.iat[4 , 2 ] df.loc[0 ].iat[1 ]
.get 可以做类似字典的操作,如果无值给返回默认值(例中是0):
1 2 3 4 df.get('name' , 0 ) df.get('nameXXX' , 0 ) s.get(3 , 0 ) df.name.get(99 , 0 )
表达式筛选 []
切片里可以使用表达式进行筛选:
1 2 3 4 5 6 7 df[df['Q1'] == 8] # Q1 等于8 df[~(df['Q1'] == 8)] # 不等于8 df[df.name == 'Ben'] # 姓名为Ben df.loc[df['Q1'] > 90, 'Q1':] # Q1 大于90,显示Q1后边的所有列 df.loc[(df.Q1 > 80) & (df.Q2 < 15)] # and 关系 df.loc[(df.Q1 > 90) | (df.Q2 < 90)] # or 关系 df[df.Q1 > df.Q2]
df.loc
里的索引部分可以使用表达式进行数据筛选。
1 2 3 4 5 6 7 8 9 10 df.loc[df['Q1'] == 8] # 等于8 df.loc[df.Q1 == 8] # 等于8 df.loc[df['Q1'] > 90, 'Q1'] # Q1 大于90,只显示 Q1 Series df.loc[df['Q1'] > 90, ['Q1']] # Q1 大于90,只显示 Q1 DataFrame # 其他表达式与切片一致 # 通过列位置筛选列 df.loc[:, lambda df: df.columns.str.len()==4] # 真假组成的序列 df.loc[:, lambda df: [i for i in df.columns if 'Q' in i]] # 列名列表 df.iloc[:3, lambda df: df.columns.str.len()==2] # 真假组成的序列
逻辑判断和函数:
1 2 3 4 5 6 7 8 9 df.eq() # 等于相等 == df.ne() # 不等于 != df.le() # 小于等于 >= df.lt() # 小于 < df.ge() # 大于等于 >= df.gt() # 大于 > # 都支持 axis{0 or ‘index’, 1 or ‘columns’}, default ‘columns’ df[df.Q1.ne(89)] # Q1 不等于8 df.loc[df.Q1.gt(90) & df.Q2.lt(90)] # and 关系 Q1>90 Q2<90
其他函数:
1 2 3 # isin df[df.team.isin(['A','B'])] # 包含 AB 两组的 df[df.isin({'team': ['C', 'D'], 'Q1':[36,93]})] # 复杂查询,其他值为 NaN
函数筛选 函数生成具体的标签值或者同长度对应布尔索引,作用于筛选:
1 2 3 df[lambda df: df['Q1'] == 8] # Q1为8的 df.loc[lambda df: df.Q1 == 8, 'Q1':'Q2'] # Q1为8的, 显示 Q1 Q2 # 选择字段时尽量使用字典法,属性法在条件表达式时一些情况可能有 bug
函数不仅能应用在行位上,也能应用在列位上。
str查询 模糊查询 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 data[data.列名.str .contains()] data[data.列名.str .contains('^某某' )] data[data.列名.str .contains('某某' )] data[data.列名.str .contains('某某$' )] data['列名' ]=data['列名' ].apply(str ) data[data.source.str .contains('某某|某某1' )] data[-data.source.str .contains('某某|某某1' )] DataFrame.drop_duplicates(subset=None ,keep='first' ,inplace=False ) data.drop_duplicates(subset='列名' ,keep='first' ,inplace=False ) data.drop_duplicates(subset=['列名' ,'列名1' ],keep='first' ,inplace=False )
df内置方法 where 和 mask 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 s.where(s > 90 ) s.where(s > 90 , 0 ) np.where(s>80 , True , False ) np.where(df.num>=60 , '合格' , '不合格' ) s.mask(s > 90 ) s.mask(s > 90 , 0 ) m = df.loc[:,'Q1' :'Q4' ] % 3 == 0 df.loc[:,'Q1' :'Q4' ].where(m, -df.loc[:,'Q1' :'Q4' ]) df.lookup([1 ,3 ,4 ], ['Q1' ,'Q2' ,'Q3' ]) df.lookup([1 ], ['Q1' ])
mask 和 where 还可以通过数据筛选返回布尔序列:
1 2 3 4 5 # 返回布尔序列,符合条件的行为 True (df.where((df.team=='A') & (df.Q1>60)) == df).Q1 # 返回布尔序列,符合条件的行为 False (df.mask((df.team=='A') & (df.Q1>60)) == df).Q1
query 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 df.query('Q1 > Q2 > 90' ) df.query('Q1 + Q2 > 180' ) df.query('Q1 == Q2' ) df.query('(Q1<50) & (Q2>40) and (Q3>90)' ) df.query('Q1 > Q2 > Q3 > Q4' ) df.query('team != "C"' ) df.query('team in ["A","B"]' ) df.query('team not in ("E","A","B")' ) df.query('name.str.contains("am")' ) df.query('B == `team name`' ) a = df.Q1.mean() df.query('Q1 > @a+40' ) df.query('Q1 > `Q2`+@a' ) df[df.eval ("Q1 > 90 > Q3 > 10" )] df[df.eval ("Q1 > `Q2`+@a" )]
filter 使用 filter 可以对行名和列名进行筛选。
1 2 3 4 5 6 7 df.filter (items=['Q1' , 'Q2' ]) df.filter (regex='Q' , axis=1 ) df.filter (regex='e$' , axis=1 ) df.filter (regex='1$' , axis=0 ) df.filter (like='2' , axis=0 ) df.filter (regex='^2' , axis=0 ).filter (like='Q' , axis=1 )
关于 filter 的详细介绍,可以查阅:Pandas filter 筛选标签 。
索引选择器 pd.IndexSlice pd.IndexSlice
的使用方法类似于df.loc[]
切片中的方法,常用在多层索引中,以及需要指定应用范围(subset 参数)的函数中,特别是在链式方法中。
1 2 3 4 5 df.loc[pd.IndexSlice[:, ['Q1', 'Q2']]] # 变量化使用 idx = pd.IndexSlice df.loc[idx[:, ['Q1', 'Q2']]] df.loc[idx[:, 'Q1':'Q4'], :] # 多索引
复杂的选择:
1 2 3 4 5 6 7 # 创建复杂条件选择器 selected = df.loc[(df.team=='A') & (df.Q1>90)] idxs = pd.IndexSlice[selected.index, 'name'] # 应用选择器 df.loc[idxs] # 选择这部分区域加样式(样式功能见教程后文介绍) df.style.applymap(style_fun, subset=idxs)
按数据类型 可以只选择或者排除指定类型数据:
1 2 3 4 5 df.select_dtypes(include=['float64' ]) df.select_dtypes(include='bool' ) df.select_dtypes(include=['number' ]) df.select_dtypes(exclude=['int' ]) df.select_dtypes(exclude=['datetime64' ])
any 和 all any 方法如果至少有一个值为 True 是便为 True,all 需要所有值为 True 才为 True。它们可以传入 axis 为 1,会按行检测。
1 2 3 4 df[(df.loc[:,['Q1' ,'Q2' ]] > 80 ).all (1 )] df[(df.loc[:,['Q1' ,'Q2' ]] > 80 ).any (1 )]
理解筛选原理 df[<表达式>] 里边的表达式如果单独拿出来,可以看到:
1 2 3 4 5 6 7 8 9 10 df.Q1.gt(90) ''' 0 False 1 False 2 False 3 True 4 False ... Name: Q1, Length: 100, dtype: bool '''
会有一个由真假值组成的数据,筛选后的结果就是为 True 的内容。
mean()
median()
unique()
value_count()
map & apply 1 2 3 4 5 6 7 8 9 10 review_points_mean = reviews.points.mean() reviews.points.map (lambda p: p - review_points_mean) def remean_points (row ): row.points = row.points - review_points_mean return row reviews.apply(remean_points, axis='columns' )
案例实操 获取指定值的索引 有时候我们需要知道指定值所在的位置,即一个值在表中的索引,可以使用以一下方法:
1 2 3 4 5 6 7 8 9 # 指定值的的索引对 np.argwhere(df.values == 'Eorge') # array([[3, 0]]) # 值为 90 的索引对 np.argwhere(df.values == 90) ''' array([[33, 2], [64, 5]]) '''
修改某行某列的值 1 2 3 4 5 import pandas as pdx2 = pd.read_csv("submit.csv" ) x2.loc[x2.id ==800000 ,'isDefault' ] = 1 x2
相关内容