df.index df.columns 注意可以直接赋值,如: df.columns = ['A', 'B', 'C'] df.values df.shape 返回元组 df.size 总个数 df.dtypes # 返回布尔值,表示对象是否为空 df.empty
pd.set_option('display.max_columns', 1000) pd.set_option('display.width', 1000) pd.set_option('display.max_colwidth', 1000)
print(df.describe()) ''' a b count 9.000000 5.000000 mean 2.777778 2.200000 std 1.201850 0.273861 min 1.000000 2.000000 25% 2.000000 2.000000 50% 3.000000 2.000000 75% 3.000000 2.500000 max 5.000000 2.500000 ''' print(df.describe(include=['object'])) #显示freq最高的对象 print(df.describe(include='all'))
asc_sorted_df = unsorted_df.sort_index() desc_sorted_df = unsorted_df.sort_index(ascending=False) col_sorted_df = unsorted_df.sort_index(axis=1)
注意:若前面没有=,一定要带inplace=True, 否则不起作用
col1_sorted_df = unsorted_df.sort_values(by='col1') col1_col2_sorted_df = unsorted_df.sort_values(by=['col1', 'col2']) # 实际过程中:若想取到排序之后的第一行行号 df_sort.index[0] # 或者使用df[col_name].idxmin()或df[col_name].idxmax()
#注意:1,只能用于Series;2.返回一个Series,按照出现频率按多到少排序,index为原value print(data['a'].value_counts()) # 注意以下方法只适合目标value为0,1类型的数据 # 巧用value_counts()和groupby计算不同...类型...的比率 cp_count = data['cp'].value_counts() # cp为胸痛类型 # 输出为Series gr_cp_sum = data.groupby('cp')['target'].sum() # target为1表示患病,0表示不患病 # 输出为Series print('不同胸痛类型的就诊者所患病的比率\n', round(gr_cp_sum / cp_count, 2))
# 注意不要被reindex的名字所迷惑,其功能类似于切片,如:取0,2,100行,'A', 'B', 'Z'列;不同之处是,可以是原df中不存在的行或列,生成新的df中,这里行或列为NaN df_reindexed = df.reindex(index=[0,2,100], columns=['A', 'B', 'Z']) # 若想重建索引,直接给df.index赋值即可 df.index = range(len(df)) df1 = pd.DataFrame(np.random.randn(6,3),columns=['col1','col2','col3']) df2 = pd.DataFrame(np.random.randn(2,3),columns=['col1','col2','col3']) df1 = df1.reindex_like(df2) # 必须确保df1和df2列明相同 # rename通过字典结构重建 print(df1.rename(columns={'col1':'c1','col2':'c2'},index ={0 :'apple',1 :'banana',2 :'durian'})) # reset_index 将旧索引添加为列,并使用新的顺序索引----> 多用于使用多个字段groupBy聚合之后 df.reset_index() daily_rental = bikeDf_time.groupby(['year','month','day','weekday','day_type'])['count'].sum().reset_index()
print(df[df.A > 0]) # A列大于0的值 # print(df[df['A'] > 0]) # 也可以这样写 ''' A B C D 2020-01-01 0.105586 -0.173702 0.360643 -1.866179 2020-01-06 2.790227 0.053426 -1.123202 0.573211 ''' print(df[(df.A > 0) & (df.B < 0)]) # 多个条件过滤:需用小括号包裹,且只能用& | ~ # 注意这里与df[df.A > 0]的区别 print(df[df > 0]) # 获取所有大于0的值,小于0设为NaN ''' A B C D 2020-01-01 0.021760 0.467921 NaN 0.442172 2020-01-02 NaN NaN NaN NaN 2020-01-03 NaN NaN NaN 0.421954 2020-01-04 NaN NaN NaN 0.254046 2020-01-05 0.970615 1.234028 1.920165 0.802954 2020-01-06 NaN NaN NaN NaN 2020-01-07 NaN 0.292532 NaN NaN ''' # 使用isin()方法进行过滤 df2 = df.copy() df2['E'] = ['one', 'one', 'two', 'three', 'four', 'three', 'two'] print(df2[df2['E'].isin(['two', 'four'])]) # 字符串类型的模糊查询 copy2 = copy.loc[copy['业务员名称'].str.contains('张|赵')]
# list删除元素(三种方法: remove、del、pop) li = ['A', 'B', 'C'] li.remove('B') del li[1] li.pop(2) # 参数是下标 # numpy删除列(一种方法: delete) a = np.arange(12).reshape(3, 4) print('第一个数组:') print(a) print('未传递Axis参数。在插入之前输入数组会被展开。') print(np.delete(a, 5)) print('删除第二列:') print(np.delete(a, 1, axis=1)) ''' 第一个数组: [[ 0 1 2 3] [ 4 5 6 7] [ 8 9 10 11]] 未传递Axis参数。在插入之前输入数组会被展开。 [ 0 1 2 3 4 6 7 8 9 10 11] 删除第二列: [[ 0 2 3] [ 4 6 7] [ 8 10 11]] ''' # DataFrame删除列(三种方法:drop、del、pop, 后面两种只能一个一个的删) df.drop('A', axis=1, inplace=True) df.drop(['A', 'B'], axis=1, inplace=True) del df['A'] df.pop('A') # Series删除某个index(三种方法:drop、del、pop, 后面两种只能一个一个的删) se.drop(['A', 'B'], inplace=True) # 注意这里不要带axis参数(只有axis=0,所以不用带) del se['A'] se.pop('A')
df = df.drop(0) # 索引名0重复被一并删除 # 根据条件删除行 df.drop(data[data['A4']==0].index, inplace=True) copy = sheet1_shee2_merge.drop_duplicates('业务员编码', inplace=False) # 是直接在原来数据上修改还是保留一个副本 # 统计数据重复 print('sheet1订单号重复检查:') print(sheet1Df['订单号'].duplicated().value_counts()) # 结果为series, index为False和True, 值分别为不重复和重复的数量 # 所有列的值一样视为重复 print(data.duplicated().value_counts()) data.drop_duplicates(inplace=True)
前者:字典的key是创建index
后者:字典的key是创建columns
# 省略方式取列的方法 df['B'] # 取一列 df[['A', 'B']] # 取多列 # 唯一可以省略方式取行的方法:必须使用冒号(其它方式使用loc或iloc) df[2:4] # 参数是行索引号,结果为2行(等同于df.iloc[2:4, :]) df['20220806': '20220808'] # 行名,结果为3行 (等同于df.loc['20220806': '20220808', :]) # loc方法(貌似行号不能非连续)(注意loc中的参数冒号都是取头又取尾,不管index是不是默认或数值型) df.loc[:, ['A', 'C']] df.loc['20220806'] df.loc['20220806': '20220808', ['A', 'C']] df.loc['20220806', ['A', 'C']] df.loc['20220806', 'A':'C'] # iloc方法(行索引和列索引都可以不连续)(注意iloc中的参数冒号都是取头不取尾) df.iloc[2:4, 0:2] df.iloc[[2, 4], [0, 2]] df.iloc[1, 1] df.loc['b':'e'] # 是包含e行的 df.iloc[1:4] # index从1到3,不包含4
df['one'].isnull() df['one'].notnull() df['one'].sum() # 若有缺失数据(NaN),求和时视为0,这里不会报错 # 查看数据缺失情况 # 方法一 print(df.info()) # 方法二(推荐) print(df.isnull().sum()) # 生成一个Series # 方法三:1表示不含缺失值,2表示含缺失值(notnull()结果只有True和False) print(df.notnull().nunique()) df.fillna(0) # 对某一列进行处理 df['A2'] = df['A2'].fillna(1) df['A7'] = df['A7'].fillna(df['A7'].mean()) # 查看众数的方法 # 1表示不含缺失值,2表示含缺失值(notnull()结果只有True和False) print(df.notnull().nunique()) # pad/fill 填充方法向前 # bfill/backfill 填充方法向后 df.fillna(method='pad') df.dropna() # 默认axis=0,按行删除,若一行中有NaN,删除该行 df.dropna(axis=1) # 按列删除 df.dropna(inplace=True, thresh=10) # thresh表示非NaN行数,小于此值就删除 # 利用方法replace df.replace({1000: 10, 2000: 20}) data['chol'].replace(564,246,inplace=True)
数据分析空处理规则:
NaN -- 默认值(政策、法规、规范)
NaN -- 序列型用中位数(median)、数值型用均值(mean)、类别型用众数(mode, 注意其结果为Series, 需要加[0]) (序列型:如疾病的严重程度,一般分为轻1、中2、重度3,数字大小有严重等级关系)(类别型:如血型,一般分为A、B、O、AB四个类型,用1-4表示,数字大小没有等级关系)
data['小区房屋出租数量'] = data['小区房屋出租数量'].fillna(data['小区房屋出租数量'].mean()) data['地铁站点'] = data['地铁站点'].fillna(data['地铁站点'].median()) data['出租方式'] = data['出租方式'].fillna(data['出租方式'].mode()[0])
NaN -- 向前、向后(数据波动有规律)
NaN -- replace(明显错误)
NaN -- 逼近值(拉格朗日opp、牛顿差值oop)
NaN -- 删除(少于5%,不一定)行、列 (利用参数thresh(有效数据的最低要求), 5%需要手动计算一下)
Pearson相关系数
df.copy(deep=true)
def adder(ele1,ele2): return ele1+ele2 df=df.pipe(adder,20) # 方法1通过pipe调用操作函数,并设置叠加值 # df+=20 # 方法2直接将df叠加值即可,pandas最新管道用法 print('管道将DataFrame的所有元素叠加20:') #通过map函数仅对指定列运算 myArray=np.random.randn(5,3) print(myArray) df = pd.DataFrame(myArray,columns=['col1','col2','col3']) df=df['col1'].map(lambda x:x*100)
df.apply(aggfunc) axis = 0(默认),按列处理;axis=1,按行处理,将一行作为一个Series传入aggfunc中
se.map(aggfunc) 它是Series的函数,aggfunc只能传入一个参数
df.pct_change() df.cov(df2) df.corr(df2)
df.aggregate(np.sum) # 可以简写为df.agg df['A'].aggregate(np.sum) df[['A','B']].aggregate(np.sum) df['A'].aggregate([np.sum,np.mean]) # 分组 print(df.groupby('Team').groups) # 注意df.groupby('Team')结果显示的是对象内存 grouped = df.groupby('Year') # 其结果是一个元组(groupby_name, df_group),它可以用for进行遍历 #查看分组 print(grouped.get_group(2014)) # 获取某个组别数据 # 聚合(aggregate) - 先分组,再聚合 # 使用numpy标准函数:若使用一个函数(且不带中括号),生成一个Series, 否则生成一个DataFrame,列名为函数名,如sum,mean print(grouped['Points'].agg(np.mean)) print(grouped['Points'].agg([np.sum, np.mean, np.std])) # 注意与上面的区别:上面生成一个Series, 字典方式和带中括号方式都是生成一个DataFrame print(grouped['Points'].agg([np.mean])) # 带中括号就会生成DataFrame print(grouped.agg({'Points': np.mean})) # 使用字典方式实现不同字段使用不用聚合函数(包含自定义函数) # 注意这里的区别:groupby后直接agg,不用取某一个字段 df_gr = data.groupby('No').agg({'Close': cal_perc_fun, 'Volume': np.sum, 'High': np.amax, 'Low': [np.amin, np.amax] }) # 其中cal_perc_fun为自定义函数,也可以写成lambda函数 # 生成的df_gr字段,若没有一个字段多个函数,直接就是字段名;否者为复合字段名,为元组形式,如: #MultiIndex([('Close','cal_perc_fun'),('Volume','sum'),('High','amax'),('Low','amin'),( 'Low','amax')]) # 取值方式:df_gr[('Low', 'amin')] # 使用自定义函数 print(grouped['Points'].transform(lambda x: (x-x.mean())/x.std * 10)) # 过滤 print(df.groupby('Team').filter(lambda x: len(x) > 3)) # 返回三次以上参加的队伍
''' step4:数据透视表操作,每个地区的业务员分别赚取的利润总和与利润平均数 ''' pivot_table = pd.pivot_table(sheet1_shee2_merge, index='地区名称', columns='业务员名称', values='利润', aggfunc=[np.sum, np.mean]) print('每个地区的业务员分别赚取的利润总和与利润平均数透视表:') print(pivot_table) print('********************************************************************') ''' sum ... mean 业务员名称 倪仲涛 刘仕祯 卞思宝 吴雯龙 尚庆龙 ... 陈国聚 陈恩泽 高鹏 麦豪 黄佳成 地区名称 ... 上海 NaN NaN NaN NaN NaN ... NaN 30.0 200.0 780.0 360.0 北京 NaN NaN 420.0 NaN NaN ... NaN NaN NaN NaN NaN 广州 300.0 170.0 NaN NaN 1200.0 ... NaN NaN NaN NaN NaN 深圳 NaN NaN NaN 330.0 NaN ... 3200.0 NaN NaN NaN NaN [4 rows x 40 columns] '''
# 分布统计不同赛季输和赢的场数 knicks2 = pd.crosstab(knicks.season, knicks.win) ''' win L W season 07-08 59 23 08-09 50 32 09-10 53 29 10-11 40 42 11-12 30 36 '''
# 当值只有两类时 df['win_flag'] = df['win'].map({'L': 0, 'W': 1}) # 当值有多类时 def dummies(data, col_name_list): for col_name in col_name_list: # 类别大于2类的列做哑变量处理 if len(data[col_name].value_counts()) > 2: tempDf = pd.get_dummies(data[col_name], prefix=col_name) data = pd.concat([data, tempDf], axis=1) data.drop(col_name, axis=1, inplace=True) return data
bins = [0, 1932, 2345, 10000] groups = ['低', '中', '高'] Dataframesale['分组'] = pd.cut(df['利润'], bins, labels=groups) print(df) print('********************************************************************') ''' 地区名称 利润 分组 0 上海 1970.0 中 1 北京 1820.0 低 2 广州 2720.0 高 3 深圳 8330.0 高 '''
rs = pd.merge(left, right, on='id') rs = pd.merge(left, right, on=['id', 'subject_id']) # 若连接的表之间有相同字段,可以通过参数suffixes加后缀,默认为['_x', '_y'] df_mer = pd.merge(df_2015, df_2016, on=['Month', 'Day', 'Hour'], suffixes=['_2015', '_2016']) rs = pd.merge(left,right,on='subject_id',how='left') # left/right/outer(全连接)/inner 默认为inner
ignore_index设置为True生成连续索引
rs = pd.concat([one,two], keys=['x','y'], ignore_index=True) #使用keys把特定的键与每个碎片的DataFrame关联起来 #ignore_index设置为True生成连续索引,一般在axis=0时使用 rs = pd.concat([one,two], axis=1) #横向合并 注意多个df一定要用[] rs = one.append(two) rs = one.append([two, one, two])
df = pd.read_csv('temp.csv', index_col=['S.No']) # 使用某列作为索引 df = pd.read_csv('temp.csv', dtype={'Salary': np.float64}) # 更改某列的数据类型 # 使用header指定标题行,使用names自定义列名 df = pd.read_csv('temp.csv', names=['a', 'b', 'c'], header=0) # skiprows跳到指定行数开始显示 df = pd.read_csv("temp.csv", skiprows=2)