普通筛选
# loc筛选:选择符合条件的行 df.loc[df["grade"] == "B"].head() # 选择符合条件的行和特定的列 df.loc[df["grade"] == "B", ["member_id", "grade"]].head() # 选择符合条件的行和特定的列,并排序 df.loc[df["grade"] == "B", ["loan_amnt", "grade"]].sort(["loan_amnt"]) # 多条件筛选 df.loc[[(df["gradd"]=="B") & (df["loan_amnt"]>5000), ["member_id", "term" ]].head() # 反选 data[~((data.发布时间.isnull()) & (data.实际首试日期 < '2018-11-1'))] # 反转行 df.iloc[::-1, :]
逻辑判断后筛选
# isin筛选 df["A"].isin([1,2,3]) # 多条件 df[(df.AAA <= 6) & (df.index.isin([0, 2, 4]))] # loc和isin组合 df.loc[df['sepal_length'].isin([5.8,5.1])] # 字符串isin df.loc[df['grade'].isin(['北京','上海'])] # 字符串开头 df[df['A'].str.startswith('北京')] # contains筛选 df[df['商品名称'].str.contains("四件套")] # 多个筛选 df_re =df[df['公司'].str.contains('公司A||公司B')] # 筛选含特殊字符的 df[df['产业线'].str.contains('\?')] # 多条件筛选 data[(data['var1'].str[0] == 'M')&(data['var2'].apply(lambda x : str(x)[0] == '8'))] # 索引特殊用法 df[[i.endswith('A') for i in df.index]] # 按字符串长度筛选 data = df[df['名称'].str.len()>5] # 按字符串开头筛选 df[df['名称'].str[0] == 'M'] # 筛选列 data = data.loc[:,~(data.columns.str.contains('集团'))] # 筛选前几个最大值 data = df.iloc[df['名称'].nlargest(3).index] # 筛选由汉字开头的数据 df = df[df['名称'].str.contains(r'^[\u4e00-\u9fa5]')] # 日期不是索引时, 按日期筛选 data[data['时间'].apply(lambda x: x.year == 2019)] data[data['时间'].apply(lambda x: x.strftime('%Y%m')=='202008')]
分组后筛选
# 分组后筛选前2个 df2 = df1.groupby(['class']).head(2) # 分组后筛选第2条或者倒数第2条数据 df1.groupby('class').apply(lambda i:i.iloc[1] if len(i)>1 else np.nan) df1.groupby('class').apply(lambda i:i.iloc[-2] if len(i)>1 else np.nan) # 分组后按条件筛选 data.groupby('var1').filter(lambda x: len(x[x['var2']=='A'])>=1) data.groupby('公司编码').filter(lambda x:len(x)!=3) # groupby筛选方法1(先分组,然后筛选另一个变量中最小值) df.loc[df.groupby('AA')['BB'].inxmin()] #groupby筛选方法2:(先排序,分组,然后筛选每一组中的第一个) df.sort_values(by='BB').groupby('AA',as_index=False).first() # groupby筛选方法3:groupby与apply结合 df.groupby('aa').apply(lambda x : x['BB'][x['cc'].idxmax()] # 分组并排序 df[['A','B']].groupby('A').mean().sort_values('B',ascending=False).head()
替换
# 单个替换 df['判断'].replace(['B','C'],np.nan,inplace=True) #支持正则表达式 # 多个替换 data['var'].replace(['A','B'],['a','b'],inplace=True) # loc原地替换 df1.loc[df['sex']=='female', 'sex'] = 1 df1.loc[df['sex']=='male', 'sex'] = 0 # 字典 df.replace({'female':1, 'male':0}) # 适合二分法 df1['sex'] = df1['sex'].map(lambda x:1 if x=='female' else 0) # apply df_zb['var'] = df_zb['var'].apply(lambda x: x[:-1] if x[-1].isalpha() else x) data3['var'] = data3['var'].apply(lambda x: x[:-1] if x[-1] == 's' else x) # np.where data['var'] = np.where(data['var'] == ' ',0,data['var'])
字符串处理
print('我的名字是%s,今年%i岁,体重%.2f'%('小明',20,70.1)) # 去除空格,改变大小写 df['term'] = df['term'].map(str.strip) #去除左右两边的空格,strip后面是否带括号 df['term'] = df['term'].str.strip() df['term'] = df['term'].map(str.lstrip) #去除左边的空格 df['term'] = df['term'].map(str.rstrip) #去除右边的空格 df['term'] = df['term'].map(str.upper) # 改成全部大写 df['term'] = df['term'].map(str.lower) # 改成全部小写 df['term'] = df['term'].map(str.title) # 改成首字母大写 # 去掉所有空格 data = data.applymap(lambda x: x.strip() if isinstance(x,str) else x)
字符串判断
# 判断是否为某一特定格式 df['emp_length'].apply(lambda x: x.isalpha()) #是否为字母 df['emp_length'].apply(lambda x: x. isalnum ()) #是否全未数字或者字母 df['emp_length'].apply(lambda x: x. isdigit ()) #是否为数字
字符串拆分
s.str.split('_') # 拆分,结果是列表 s.str.split('_').str.get(1) # 拆分后取第一个,可用于生成新变量 s.str.split('_').str[1] # 拆分后取第一个,可用于生成新变量 s.str.split('_', expand=True) # 拆分,并展开成多列 s.str.split('_', expand=True, n=1) # 按第一个拆分 s.str.rsplit('_', expand=True, n=1) # 按最后一个拆分 data['var'] = data['var'].str.split('?',expand=True)[0]
索引
# 把列变成索引 df.set_index('时间',inplace=True, drop = False) df.set_index(['r','s'], inplace = True) # r为一级,s为二级 # 取消层次化索引,将索引变回列 df.reset_index(inplace=True) df.reset_index(drop=True,inplace=True,level = None) # 按索引排序 df.sort_index(inplace=True,ascending=False) # 更新索引(行、列都可以修改) df2 = df1.reindex(['a','b','c','d','e']) # 返回一个新的DataFrame,按新的索引进行排序 df2 = df1.reindex(['a','b','c','d','e'], fill_value=0) # 多级索引问题(索引可以在行,也可以在列) df.index.names=['类型','供应商'] # 取名称 df.columns.names=['类型','日期'] # 取名称 df1 = df.swaplevel('类型','日期',axis=1) #调整多级索引次序 df1 = df.sort_index(level=0, axis=1, ascending=True,sort_remaining=False) # sort_remaining 默认是True df1 = df.sum(axis=1,level='类型') # 通过索引对多列进行求和
排序
# na_position对NaN值的处理方式,可以选择first和last两种方式 df.sort() # 单列排序 df.sort(["loan_amnt"],ascending=False) # 降序 # 多列进行排序,加入一个列表 df.sort(["loan_amnt","int_rate"],ascending=False) # 升序排列后选择前10 df.sort(["loan_amnt"],ascending=True).head(10) # 自定义排序 df.sort_values(by=['日期','类型','距离'],ascending=True,inplace=True,na_position = 'last') # 索引排序 df.sort_index(inplace=True)
日期
# 设置成日期格式 df['创建日期'] = pd.to_datetime(data_final['创建日期'],format='%Y/%m/%d') # 设置为日期索引 df.set_index('订单提交时间',inplace=True) # 日期索引排序 df.sort_index(inplace=True,ascending=False) # 日期索引的筛选 df_2019 = df['2019'] # 日期索引可以直接这样筛选 df['2019-01'] #按月筛选 df['2019-03-12':'2019-03-12'] #筛选某一天数据 # 改变显示频率(只针对日期索引) df = df.to_period('M') # 针对索引,关键步骤 Q 季度 Y年 D天 # 计算时间间隔 data['间隔天数'] = list(map(lambda x: x.days, pd.to_datetime('today') - data['生产时间'])) df['天数'] = df['天数'].apply(lambda x: x.days) # 单独表示间隔天数 from datetime import timedelta aDay = timedelta(days=1) # 时间对象格式化 df['DATE'] = [datetime.strftime(x,'%Y-%m-%d') for x in df['DATE']] # 时间分组后计算 final = data.groupby(data['订单时间'].apply(lambda x: x.strftime('%Y%m')))['总价'].sum()/10000 data.groupby(data['日期'].apply(lambda x: datetime.strftime(x,'%Y-%m-%d')))['var'].count() data.set_index('日期').groupby('供应商')['数量'].rolling('7D').sum().reset_index() final1 = data.groupby([data.to_period('Q').index,'var']).apply(lambda g: np.average(g['var2'], weights=g['模次'])).reset_index() # 当前时间 import time starttime = time.time() # 当前日期 tim = time.strftime("%Y-%m-%d%H%M%S", time.localtime()) # pd.date_range 时间戳 pd.period_range 时间周期 pd.timedelta_range 时间间隔 datelist = pd.date_range('2020/11/21', periods=5) datelist = pd.date_range('2020/11/21', periods=5,freq='M') # 生成的数据是每月月初 index= pd.date_range('2019/02/01', periods=23,freq='MS') pd.date_range('2017-01-01 01:00:00', '2017-01-01 02:00:00', freq= '5min') # 当前日期前3天 import pandas as pd from datetime import datetime import time lis = pd.date_range(end='2021-4-21',periods=3) str_lis = [datetime.strftime(x,'%Y-%m-%d') for x in lis] lis = pd.date_range(end=time.strftime("%Y/%m/%d"),periods=3) str_lis = [datetime.strftime(x,'%Y-%m-%d') for x in lis]
判断是否为假期
import datetime import chinese_calendar demo_time = datetime.date(2018, 10, 2) # 判断是否是节假日 data_is_holiday = chinese_calendar.is_holiday(demo_time) # True # 判断某日是否工作日 data_is_workday = chinese_calendar.is_workday(demo_time) # False
数据分组
# 方法1 data['for_m'] = pd.cut(data['fortune_x'],[0,50,70,500],labels = ['财低','财中','财高']) # 方法2 df = pd.DataFrame({'value': np.random.randint(0, 100, 20)}) labels = ["{0} - {1}".format(i, i + 9) for i in range(0, 100, 10)] df['group'] = pd.cut(df.value, range(0, 105, 10), right=False, labels=labels)
多表合并
# 默认纵向连接,产生新的坐标轴 df = pd.concat([df1,df2],ignore_index=True) # merge 合并 pd.merge(left, right, left_on="lkey", right_on="rkey",suffixes=("_left", "_right")) pd.merge(df, df, left_on=['','',''], right_on=['','',''], suffixes=('','')) # append 表头一致的多张表,进行连接(上下连接) df1.append(df2).append(df3) # combine_first 数据填补.有两张表left和right,一般要求它们的表格结构一致,数据量也一致,使用right的数据去填补left的数据缺漏, 如果在同一位置left与right数据不一致,保留left的数据 df1.combine_first(df2)
常用函数
count()非空观测数量 sum()所有值之和 mean()所有值的平均值 median()所有值的中位数 mode()值的模值 std()值的标准偏差 var()方差 min()所有值中的最小值 max()所有值中的最大值 abs()绝对值 prod()数组元素的乘积 cumsum()累计总和 cumprod()累计乘积 skew()偏斜 kurt()峰度 quantile()分位数 apply()通用申请 cov()协方差 corr() 相关系数
描述性统计
df.describe(include=['object']) #object - 汇总字符串列 number - 汇总数字列 all - 将所有列汇总在一起(不应将其作为列表值传递) df.describe().round(2) # 只保留两位小数 df.describe().round(2).T #只保留两位小数并转置 df.groupby('性别').describe().unstack() df.groupby('性别')['身高'].describe().unstack() df.round(3) # 数据可以取消科学计数法? df = df.round(0) # 都改为整数 # 保留2位小数 df['a']=df['mean'].round(decimals=2) df['b']=df['mean'].map(lambda x:("%.2f")%x) df['c']=df['mean'].map(lambda x:format(x,".2%")) description = [data.min(), data.max(), data.mean(), data.std()] # 依次计算最小值、最大值、均值、标准差 description = pd.DataFrame(description, index = ['Min', 'Max', 'Mean', 'STD']).T # 将结果存入数据框 print('描述性统计结果:\n',np.round(description, 2))