Pandas 简介 Pandas 是 python 的一个数据分析包,最初由 AQR Capital Management 于 2008 年 4 月开发,并于 2009 年底开源出来,目前由专注于 Python 数据包开发的 PyData 开发 team 继续开发和维护,属于 PyData 项目的一部分。Pandas 最初被作为金融数据分析工具而开发出来,因此,pandas 为时间序列分析提供了很好的支持。 Pandas 的名称来自于面板数据(panel data)和 python 数据分析(data analysis)。panel data 是经济学中关于多维数据集的一个术语,在 Pandas 中也提供了 panel 的数据类型。
Pandas 官网文档: https://pandas.pydata.org/pandas-docs/stable/
Numpy 官方文档: https://docs.scipy.org/doc/
Pandas 数据类型 Pandas 所支持的数据类型:
float/float64
int/int64
bool
datetime64[ns]
datetime64[ns, tz]
timedelta[ns]
category
object
Pandas 增加 指定列名:
1 df.to_csv("cnn_predict_result.csv" ,encoding="utf_8_sig" ,index=False ,columns=columns)
数据汇总:
1 2 3 groupby_col = ["a" ,"b" ,"c" ] sum_col = "amount" df_new = df.groupby(groupby_col)[[sum_col]].sum ()
DataFrame 转 list:
1 np.array(data_x).tolist()
字符串按照 | 分割:
1 data['name' ].str .split('|' ,expand=True )
series 转 DataFrame 处理:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 a= df.groupby(groupby_col)[sum_col].sum () In [169 ]: a.to_frame() Out[169 ]: _key cust_name cust 吐尔逊姑阿吾提 384 384 帕拉哈提 6203 6203 帕提古力·麦麦提赛来 6109 6109 海生林 1372 1372 In [185 ]: a.reset_index() Out[185 ]: cust_name cust _key 0 吐尔逊姑阿吾提 384 384 1 帕拉哈提 6203 6203 2 帕提古力·麦麦提赛来 6109 6109 3 海生林 1372 1372
按照数据类型区分:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 In [73 ]: df Out[73 ]: aa bb cc 0 a b c1 1 2 3 2 2 3 4 In [71 ]: df[df["aa" ].isin([2 ])] Out[71 ]: aa bb cc 2 2 3 4 In [72 ]: df[df["aa" ].isin(["a" ])] Out[72 ]: aa bb cc 0 a b cset (list (df.agg("aa" )))
判断空值:
df[‘$open’].isnull().any() # 判断 open 这一列列是否有 NaN df[‘$open’].isnull().all() # 判断 open 列是否全部为 NaN
字符切割,切割中文:
必须要 utf-8 编码
使用 slice 切割
全空列先剔除
1 2 3 4 df = pd.read_csv(file_path,sep='|' ,low_memory=False ,encoding='utf-8' ) if df[col].isnull().all (): continue df[col] = df[col].str .slice (start=0 ,stop=-2 ,step=None )
low_memory:
默认 low_memory=True,使用低内存加载数据,但是可能存在类型混淆的情况 需要 low_memory=False 或者指定字段类型
1 df = pd.read_csv('somefile.csv' , low_memory=False , dtype=str )
pandas 转换为时间格式 df = pd.read_csv(fp, dtype=str,sep=’|’) df[“JY_JYSJ”] = pd.to_datetime(df[“JY_JYSJ”], format=”%Y-%m-%d%H:%M:%S”) df.to_csv(fp, index=False,sep=’|’)
Pandas 删除 删除 指定列。含空数据的行:
1 2 可以通过subset参数来删除在age和sex中含有空数据的全部行 df4 = df4.dropna(subset=["age" ,"sex" ])
删除 全空列:
1 2 df = df.dropna(axis=1 ,how='all' ) axis参数说明axis = 1 行处理 默认axis = 1 列处理
删除含有空数据的全部行
1 2 df4 = pd.read_csv('4.csv' , encoding='utf-8' ) df4 = df4.dropna()
删除含有空数据的全部列
1 2 可以通过axis参数来删除含有空数据的全部列 df4 = df4.dropna(axis=1 )
Pandas 修改 精度处理 df.round({‘A’: 1, ‘C’: 2})
字段重命名:
$a
重命名为 a 无返回值 d
1 2 df.rename(columns={'$a' : 'a' , '$b' : 'b' }, inplace=True )
指定列填充值:
1 2 col = "aaaaa" df[col] = df[col].ffill(0 )
列函数处理:
1 2 c=c[["a" ,"b" ]].apply(foo,axis=1 )
数据去重 drop_duplicates:
1 2 df.drop_duplicates([cols],inplace=True ) df.drop_duplicates(subset='id:ID' ,keep='first' ,inplace=True )
查看开头为 xxx 的字符 .str.startswith(‘0’):
1 df["JY_FROM_CERTID" ] = df[df["JY_FROM_CERTID" ].str .startswith('0' )]
去除指定左边开头的字符 str.lstrip(“9”):
1 df["JY_FROM_CERTID" ] = df["JY_FROM_CERTID" ].str .lstrip("9" )
pandas 列类型转换为 日期格式:
1 2 3 4 5 6 7 df['date' ] = pd.to_datetime(df['date' ]) df.set_index("date" , inplace=True ) df2.index = pd.DatetimeIndex(df2["date" ]) del df2["date" ]结论:.to_datetime仅转换格式,.DatetimeIndex还能设置为索引
类型转换:
1 2 3 str float int datetimedf[col] = df[col].astype('str' )
替换科学计数法:
将字段类型转为 int64,即可去除科学计数法。 但是空值转换会报错,所以需要先填充空值
1 2 data2[['col1' ,'col2' ]] = data2[['col1' ,'col2' ]].fillna(-1 ) data2[['col1' ,'col2' ]] = data2[['col1' ,'col2' ]].astype('int64' ,errors='ignore' )
当 int 类型进行 concat 合并的时候,有可能会出现科学计数法,需要先转为 object.
Numpy 全局设置无科学计数法:
1 2 3 4 import numpy as npnp.set_printoptions(suppress=True , threshold=np.nan)
Pandas 全局设置完整输出:
1 2 3 4 import pandas as pdpd.set_option('display.max_columns' , 10000 , 'display.max_rows' , 10000 )
数据合并:
参考链接:
1 2 concatdf_new = pd.concat([df1,df2])
Pandas 查询 列表查询 in 和 not in:
方法 1: merge 实现
1 2 3 4 5 6 7 8 9 df = pd.DataFrame({'countries' :['US' ,'UK' ,'Germany' ,'China' ]}) countries = pd.DataFrame({'countries' :['UK' ,'China' ], 'matched' :True }) df.merge(countries,how='inner' ,on='countries' ) not_in = df.merge(countries,how='left' ,on='countries' ) not_in = not_in[pd.isnull(not_in['matched' ])]
方法 2: apply
1 2 criterion = lambda row: row['countries' ] not in countries not_in = df[df.apply(criterion, axis=1 )]
pandas 行列循环:
Pandsa 注意事项 replace 会导致空列类型变更,object->float:
1 tran_dfs[col] = tran_dfs[col].replace("nan" ,np.nan)
astype(str)会导致空值变成字符串 nan:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 tran_dfs[col] = tran_dfs[col].astype(str ) Pandas天坑: 1 、replace,使用replace必须注意method参数,默认为"pad" 及填充,会造成replace("" , None ) 用前值进行补充,必须改为method=None 2 、pd.isnull 使用isnull判断时,空值string不认为是空,故需要同时判别数值空或字符空时,在这之前将整个df.replace("" , np.nan, method=None )3 、groupby 若groupby字段中存在空置,会造成空置列数据不进入统计,故在group前转换为字符, df.replace(np.nan, "" , method=None )4 、merge 若两列字符进行拼接,若列中存在空置,会报错提示无法处理object 与float 类型,故merge时同样需要将列进行replace为空字符5 、将列强制类型转换为str 时,空值会变成'nan' 字符6. replace后,会造成列类型变更为float 。 列全空时会存在此情况。列不为全空时,类型不会变更。replace后会对列类型进行重新检查。从而导致列类型变更。 In [32 ]: import numpy as np;df = pd.DataFrame([[np.nan,np.nan],[np.nan,4 ],[np.nan,np.nan]],columns=['a' ,"b" ],dtype=str ) In [33 ]: df.dtypes Out[33 ]: a object b object dtype: object In [34 ]: df['a' ] = df['a' ].replace('1' ,"11111" , method=None );df.dtypes Out[34 ]: a float64 b object dtype: object
Pandas 功能模块 取出重复数据 drop_duplicates 为我们提供了数据去重的方法,那怎么得到哪些数据有重复呢? 实现步骤:
采用 drop_duplicates 对数据去两次重,一次将重复数据全部去除(keep=False)记为 data1,另一次将重复数据保留一个(keep=’first)记为 data2; 求 data1 和 data2 的差集即可:data2.append(data1).drop_duplicates(keep=False)
两列转为字典格式 使用 set_index 将 key 变更为索引列。 使用 to_dict 生成 索引-value 的字典
1 2 3 4 5 6 7 8 9 10 In [30 ]: print df[['col' ,'name' ]][0 :2 ] col name 2 ACCT_NATURE 账户属性3 ACCT_NET_CITY 开户网点_市In [29 ]: df[['col' ,'name' ]].set_index('col' ).to_dict()['name' ] Out[29 ]: {'ACCT_CLASS' : '\xe8\xb4\xa6\xe6\x88\xb7\xe7\xb1\xbb\xe5\x88\xab' , 'ACCT_CLOSE_DATE' : '\xe9\x94\x80\xe6\x88\xb7\xe6\x97\xa5\xe6\x9c\x9f' , }
中文切割 dtype=unicode
Pandas 对中文进行切割时,必须使用 unicode
1 2 3 df['CERT_LEFT_2' ] = df['CUST_CERTNO' ].str .slice (0 , 2 ) df['CERT_LEFT_4' ] = df['CUST_CERTNO' ].str .slice (0 , 4 )
日期-最大最小值 1 df['JY_JYSJ' ].astype('datetime64' ).max ()
统计出现频次 新加一行 df3.loc[‘new’] = [‘a’,’a’,’a’,’a’]
设置空列 reindex 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 In [20 ]: df Out[20 ]: a 0 1 1 2 In [21 ]: df.reindex(columns=['a' ,'b' ]) Out[21 ]: a b 0 1 NaN1 2 NaNIn [27 ]: df.dtypes Out[27 ]: a object dtype: object In [28 ]: df.reindex(columns=['a' ,'b' ]).dtypes Out[28 ]: a object b float64 dtype: object df = df.reindex(columns=['a' ,'b' ])
忽略大小写替换字符
读取时指定类型和字段名称 1 2 cust_df = pd.read_csv(nj_config['cust' ]['filepath' ], dtype=str , sep='|' , names=nj_config['cust' ]['name_code_dic' ].keys()).dropna(how="all" )
判断列空 1 2 3 4 5 df['$open' ].isnull().any () df['$open' ].isnull().all () df.isnull().all ()
数据类型转换 1 2 3 4 5 6 7 8 9 10 11 _STRICT_MODE = "raise" _MIDDLE_MODE = "coerce" _EASY_MODE = "ignore" acct_df[curr] = pd.to_numeric(acct_df[curr].astype(str ).\ str .replace("," , "" ).replace("nan" , "0" ), errors=VERIFY_MODE,downcast='float' ) end_date = pd.to_datetime(df_tranjrnl['TRAN_DATE' ], errors='coerce' ).dt.date.max ()
Pandas bool 值取反 1 2 3 4 5 6 7 8 In [16 ]: a =np.array([True ,False ,True ,True ,False ]) In [17 ]: c = (1 -a).astype(np.bool ) In [18 ]: c Out[18 ]: array([False , True , False , False , True ])
Pandas groupby + apply + sortValues 1 2 来个例子, groupby + apply + sortValues的例子 data.groupby('customer_id' )['repayment_date' ].apply(lambda x:x.sort_values(ascending=False )).reset_index()
DataFrame 转 列表数据 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 In [45 ]: import pandas as pd In [46 ]: import numpy as np In [47 ]: df = pd.DataFrame([{'a' :1 ,'b' :2 }, {'a' :4 ,'b' :3 }]) In [48 ]: df Out[48 ]: a b 0 1 2 1 4 3 In [49 ]: np.array(df) Out[49 ]: array([[1 , 2 ], [4 , 3 ]]) In [50 ]: np.array(df).tolist() Out[50 ]: [[1 , 2 ], [4 , 3 ]]
DataFrame 转 Json 数据 1 2 3 4 5 6 7 8 9 10 11 12 13 In [47 ]: df = pd.DataFrame([{'a' :1 ,'b' :2 }, {'a' :4 ,'b' :3 }]) In [51 ]: df Out[51 ]: a b 0 1 2 1 4 3 In [52 ]: df.to_json(orient="records" , force_ascii=False ) Out[52 ]: '[{"a":1,"b":2},{"a":4,"b":3}]' In [56 ]: Out[56 ]: [{'a' : 1 , 'b' : 2 }, {'a' : 4 , 'b' : 3 }]
分组时字符串拼接 1 2 3 4 5 6 7 8 9 10 11 12 13 14 In [28 ]: df Out[28 ]: dic_date dataset_name_md5 file_path file_type 0 2017 -02-28 8c77f148425e1a5c7f402661b4c8b68f TRANJRNL-60001 -2017 -02-28. csv TRANJRNL1 2017 -02-28 8c77f148425e1a5c7f402661b4c8b68f CUSTACCT-60001 -2017 -02-28. csv CUSTACCT2 2017 -02-28 8c77f148425e1a5c7f402661b4c8b68f TRANJRNL-60002 -2017 -02-28. csv TRANJRNL3 2017 -02-28 8c77f148425e1a5c7f402661b4c8b68f CUSTACCT-60002 -2017 -02-28. csv CUSTACCTIn [29 ]: df.groupby(by=['dic_date' , 'dataset_name_md5' , 'file_type' ]).aggregate(lambda x:'|' .join(x)).reset_index() Out[29 ]: dic_date dataset_name_md5 file_type file_path 0 2017 -02-28 8c77f148425e1a5c7f402661b4c8b68f CUSTACCT CUSTACCT-60001 -2017 -02-28. csv|CUSTACCT-60002 -2. ..1 2017 -02-28 8c77f148425e1a5c7f402661b4c8b68f TRANJRNL TRANJRNL-60001 -2017 -02-28. csv|TRANJRNL-60002 -2. ..
Pandas 分组时字符串列合并的方法
Pandas 日期格式化为字符串 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 tran_dates = pandas.to_datetime(df_all[tran_date_col], infer_datetime_format=True ).dt.strftime('%Y%m%d' ).unique().tolist() In [136 ]: df['dic_date' ] Out[136 ]: 0 2017 -02-28 1 2017 -02-28 2 2017 -02-28 3 2017 -02-28 Name: dic_date, dtype: object In [137 ]: pandas.to_datetime(df['dic_date' ], infer_datetime_format=True , errors="coerce" ).dt.strftime('%Y%m%d' ) Out[137 ]: 0 20170228 1 20170228 2 20170228 3 20170228 Name: dic_date, dtype: object
本对方数据翻转 本对方数据翻转 公式
1 df.loc[翻转条件, [本方,对方]] = df.loc[翻转条件, [对方,本方]]
本对方数据翻转 样例
1 2 3 4 5 6 7 df_tran.loc[df_tran["TRAN_DIRECT" ] == 'C' , ['CUST_CERTNO' , 'CUST_NAME' , 'CUST_NAMESPELL' , 'ACCT_NO' , 'CARD_NO' , 'PEER_CERTNO' , 'PEER_NAME' , 'PEER_ACCT_NAMESPELL' , 'PEER_ACCTNO' , 'PEER_CARDNO' ] ] = df_tran.loc[df_tran["TRAN_DIRECT" ] == 'C' , ['PEER_CERTNO' , 'PEER_NAME' , 'PEER_ACCT_NAMESPELL' , 'PEER_ACCTNO' , 'PEER_CARDNO' , 'CUST_CERTNO' , 'CUST_NAME' , 'CUST_NAMESPELL' , 'ACCT_NO' , 'CARD_NO' ] ].values