Python数据分析 :pandas数据读取、预处理、筛选、计算,时间序列、透视、拼接、导出

一、Pandas数据结构

S1=pd.Series([‘a’,’b’,’c’]) series是一组数据与一组索引(行索引)组成的数据结构
S1=pd.Series([‘a’,’b’,’c’],index=(1,3,4)) 指定索引
S1=pd.Series({1:‘a’,2:’b’,3:’c’}) 用字典形式指定索引
S1.index() 返回索引
S1.values() 返回值
Df=pd.DataFrame([‘a’,’b’,’c’]) dataframe是一组数据与两组索引(行列索引)组成的数据结构
Df=pd.DataFrame([[a,A],[b,B],[c,C]],columns=[‘小写’,’大写’],index=[‘一’,’二’,’三’])
Columms 为列索引,index为行索引
pip install -i https://pypi.tuna.tsinghua.edu.cn/simple pyspider 清华镜像

  • 查找某个包 anaconda search -t conda tensorflow
    下载某个包 anaconda show package
    data={‘小写’:[‘a’,’b’,’c’],’大写’:[‘A’,’B’,’C’]} 传入字典
    Df=Pd.DataFrame(data)
    Df.index() df.columns()
  • 建立分层索引的dataframe:pd.MultiIndex.from_arrays([[,,]],name=[,,])

二、读取数据

df=pd.read_excel(r’C:\user...xlsx’,sheet_name=’sheet1’) 或
pd.read_excel(r’C:\user...xlsx’,sheet_name=0) 读取excel表
pd.read_excel(r’C:\user...xlsx’,index_col=0,header=0)
index_col指定行索引,header指定列索引
pd.read_excel(r’C:\user...xlsx’,usecols=[0,1]) 导入指定列,不能有index_col和header
pd.read_tablel(r’C:\user...txt’,sep=’ ’) 导入txt文件,sep指定分隔符是什么
df.head(2) 展示前两行,默认展示前5行
df.shape 显示数据几行几列,不包含行和列索引
df.info()可查看表中数据的类型
df.describe() 可获得表中数值类型指端的分布值(和、平均值、方差等)

三、数据预处理

  • 多个Series合并成DataFrame:pd.DataFrame(list(zip(series_1, series_2)))
  • python在字符串前面加0:str(1).zfill(2)
    df.info() 可显示表中哪个数据为空
    df.isnull() 方法可以判断哪个值是缺失值,如果缺失返回True,否则为False
    df.dropna() 默认删除含缺失值的行
    df.dropna(how=’all’) 删除全为空值的行,不全为空值的行不会删除
    df.fillna(0) 用0填充所有空值
    df.fillna({‘性别’:’男’,’年龄’:’30’}) 对性别列中空值填充男,年龄填充30
  • 通过随机选择非缺失值来填充缺失值
    foo['A'].apply(lambda x: np.random.choice(
    [x for x in range(min(foo['A']),max(foo['A'])]) if (np.isnan(x)) else x)
  • 按一列数据填充另一列数据中的缺失值
    df_real['净含量'] = df_real['净含量'].fillna(df_real['净含量_y'])
  • df1.combine_first(df2):将df2的非缺失值填充df1中的缺失(dataframe根据列名和索引)值;
    ser1.combine_first(ser2):用ser2的非缺失值填充ser1中的缺失值(series根据索引)
  • 按指定的字符合并多列:df['A'].str.cat([df['B'], df['C']], sep='-')
    df.drop_duplicates(inplace=True) 默认对所有值进行重复值检查,保留第一行的值,inplace=True表示直接在原来的DataFrame上删除重复项,而默认值False表示生成一个副本。
    df.drop_duplicates(subset=’性别’) 对性别列中重复值查询保留第一行
    df.drop_duplicates(subset=[’性别’,’公司’],keep=’last’) 对性别和公司两列查重
    keep设置默认为first(保留第一个),可设置为last(保留最后一个) 或False(都不保留)
    df[‘ID’].dtype 查看ID列的数据类型
    df[‘ID’].astype(‘float’) 将ID列的数据类型转换为float类型
    数据类型:int、float、object、string、unicode、datetime
    df[‘ID’][1] ID列的第二个数据
    df.columns=[‘大写’,’小写’,’中文’] 为无索引表添加列索引
    df.index=[1,2,3] 添加行索引
    df.set_index(‘编号’) 指明要用的列作为行索列
    df.rename(index={‘订单编号’:’新订单编号’,’客户姓名’:’新客户姓名’}) 对行索引进行重新命名
    df.rename(columns={1:’一’,2:’二’}) 对列索引进行一次性重新命名所有列名
    如果你需要做的仅仅是将空格换成下划线,那么更好的办法是使用str.replace()方法,这是因为你都不需要输入所有的列名:
    df.columns = df.columns.str.replace( , _ )
    df.reset_index() 默认将全部index转化为column,
    df.reset_index(level=0) 将0级索引转化为column
    df.reset_index(drop=True) 删除原有索引
  • 多列合并为一行
    df = pd.DataFrame({'id_part':['a','b','c','d'], 'pred':[0.1,0.2,0.3,0.4], 'pred_class':['women','man','cat','dog'], 'v_id':['d1','d2','d3','d1']})
    df.groupby(['v_id']).agg({'pred_class': [', '.join],'pred': lambda x: list(x),'id_part': 'first'}).reset_index()
  • 字符串转换为数值
    df = pd.DataFrame({'列1':['1.1','2.2','3.3'],
    '列2':['4.4','5.5','6.6'],
    '列3':['7.7','8.8','-']})
    df.astype({'列1':'float','列2':'float'}).dtypes
    用这种方式转换第三列会出错,因为这列里包含一个代表 0 的下划线,pandas 无法自动判断这个下划线。为了解决这个问题,可以使用 to_numeric() 函数来处理第三列,让 pandas 把任意无效输入转为 NaN。
    df = df.apply(pd.to_numeric, errors='coerce').fillna(0)
  • 优化 DataFrame 对内存的占用
    方法一:只读取切实所需的列,使用usecols参数
    cols = ['beer_servings','continent']
    small_drinks = pd.read_csv('data/drinks.csv', usecols=cols)
    方法二:把包含类别型数据的 object 列转换为 Category 数据类型,通过指定 dtype 参数实现。
    dtypes ={'continent':'category'}
    smaller_drinks = pd.read_csv('data/drinks.csv',usecols=cols, dtype=dtypes)
  • 把字符串分割为多列
    df = pd.DataFrame({'姓名':['张 三','李 四','王 五'],
    '所在地':['北京-东城区','上海-黄浦区','广州-白云区']})
    df.姓名.str.split(' ', expand=True)
  • 把 Series 里的列表转换为 DataFrame
    df = pd.DataFrame({'列1':['a','b','c'],'列2':[[10,20], [20,30], [30,40]]})
    df_new = df.列2.apply(pd.Series)
    pd.concat([df,df_new], axis='columns')
  • DataFrame迭代:
    iterrows():将DataFrame迭代为(insex, Series)对。
    iteritems():将DataFrame迭代为(列名, Series)对。
    itertuples(): 将DataFrame迭代为元组。
    for row in df.itertuples():
    print(row)
    print('----------------')
    print(getattr(row,'col1'), getattr(row,'col2'))
    getattr() 函数用于返回一个对象属性值。

四、数据选择

  • Query是pandas的过滤查询函数,使用布尔表达式来查询DataFrame的列,就是说按照列的规则进行过滤操作。
    pandas.DataFrame.query(self, expr, inplace = False, **kwargs)
    expr:要评估的查询字符串;
    inplace=False:查询是应该修改数据还是返回修改后的副本
    kwargs:dict关键字参数
    比如要查列value_1<value_2的行记录:df.query('value_1 < value_2')
    查询列year>=2016的行记录:df.query('year >= 2016 ')
  • Insert用于在DataFrame的指定位置中插入新的数据列。默认情况下新列是添加到末尾的,但可以更改位置参数,将新列添加到任何位置。
    Dataframe.insert(loc, column, value, allow_duplicates=False)
    loc: int型,表示插入位置在第几列;若在第一列插入数据,则 loc=0
    column: 给插入的列取名,如 column='新的一列'
    value:新列的值,数字、array、series等都可以
    allow_duplicates: 是否允许列名重复,选择Ture表示允许新的列名与已存在的列名重复
    在第三列的位置插入新列:df.insert(2, 'new_col', new_col)
  • Cumsum是pandas的累加函数,用来求列的累加值。 用法:
    DataFrame.cumsum(axis=None, skipna=True, args, kwargs)
    axis:index或者轴的名字
    skipna:排除NA/null值
    df中的group列有A、B、C三组,year列有多个年份。我们只知道当年度的值value_1、value_2,现在求group分组下的累计值,比如A、2014之前的累计值,可以用cumsum函数来实现。
    当然仅用cumsum函数没办法对groups (A, B, C)进行区分,所以需要结合分组函数groupby分别对(A, B, C)进行值的累加。
    df['cumsum_2'] = df[['value_2','group']].groupby('group').cumsum()
  • Sample用于从DataFrame中随机选取若干个行或列。 用法:
    DataFrame.sample(n=None, frac=None, replace=False, weights=None, random_state=None, axis=None)
    n:要抽取的行数
    frac:抽取行的比例 例如frac=0.8,就是抽取其中80%
    replace:是否为有放回抽样, True:有放回抽样 False:未放回抽样
    weights:字符索引或概率数组
    random_state :随机数发生器种子
    axis:选择抽取数据的行还是列 axis=0:抽取行 axis=1:抽取列
    从df中随机抽取5行:df.sample(n=5)
    从df随机抽取60%的行,并且设置随机数种子,每次能抽取到一样的样本:df.sample(frac=0.6,random_state=2)
  • Where用来根据条件替换行或列中的值。如果满足条件,保持原来的值,不满足条件则替换为其他值。默认替换为NaN,也可以指定特殊值。
    DataFrame.where(cond, other=nan, inplace=False, axis=None, level=None, errors='raise', try_cast=False, raise_on_error=None)
    cond:布尔条件,如果 cond 为真,保持原来的值,否则替换为other
    other:替换的特殊值
    inplace:inplace为真则在原数据上操作,为False则在原数据的copy上操作
    axis:行或列
    将df中列value_1里小于5的值替换为0:df['value_1'].where(df['value_1'] > 5 , 0)
  • 得到DataFrame中重复的数据
    data={'one':[1,1,2,2,1,2,2],'two':['a','b','c','d','b','c','d']}
    frame=pd.DataFrame(data)
    print("***************原始数据*************")
    print(frame)
    data1 = frame.drop_duplicates(subset=['two'],keep='first')
    print("***************去重后的数据*************")
    print(data1)
    a = frame.drop_duplicates(subset=['two'],keep='last')
    b = frame.drop_duplicates(subset=['two'],keep=False)
    c=a.append(b).drop_duplicates(subset=['two'],keep=False)
    print("***************重复的数据*************")
    print(c)

df[[‘ID’,’姓名’]] 多个列名要装入list
df.iloc[[1,3],[2,4]] 用行列编号选择数据
df.iloc[1,1] 选取表中的第3行2列数据,第一行默认为列索引
df.iloc[:,0:4] #获取第1列到第4列的值
df.loc[‘一’] #loc用行名选取的行数据,格式是Series,但可以用列表形式访问
df.loc[‘一’][0] 或 df.loc[‘一’][‘序号’]
df.iloc[1]#iloc用行编号选取行数据
df.iloc[[1,3]]#多行编号选取行数据,要用list封装,不然变成行列选取
df.iloc[1:3]#选择第二行和第四行
df[df[‘年龄’]<45] #加判断条件返回符合条件的全部数据,不局限年龄列
df[(df[‘年龄’]<45)&(df[‘ID’]<4)] #判断多条件选择数据
df.iloc[[1,3],[2,4]] 相当于df.loc[[‘一’,’二’],[‘年龄’,’ID’]] #loc是名,iloc是编号
df[df[‘年龄’]<45][[‘年龄’,’ID’]]#先通过年龄条件选择行,再通过不同索引指定列
df.iloc[1:3,2:4]#切片索引

  • 行序、列序反转 :行序反转最直接的办法是使用loc函数并传递::-1,跟Python中列表反转时使用的切片符号一致
    df.loc[::-1].reset_index(drop=True)
    列序反转就比较容易了,只需要如下操作:df.loc[:, ::-1]
  • 分组里最大值所在的行方法
    分为分组中有重复值和无重复值两种。无重复值的情况。
    df = pd.DataFrame({'Sp':['a','b','c','d','e','f'], 'Mt':['s1', 's1', 's2','s2','s2','s3'], 'Value':[1,2,3,4,5,6], 'Count':[3,2,5,10,10,6]})
    df.iloc[df.groupby(['Mt']).apply(lambda x: x['Count'].idxmax())]
    先按Mt列进行分组,然后对分组之后的数据框使用idxmax函数取出Count最大值所在的列,再用iloc位置索引将行取出。有重复值的情况
    df["rank"] = df.groupby("ID")["score"].rank(method="min", ascending=False).astype(np.int64)
    df[df["rank"] == 1][["ID", "class"]]
    对ID进行分组之后再对分数应用rank函数,分数相同的情况会赋予相同的排名,然后取出排名为1的数据。
  • 选择特定类型的列
    drinks = pd.read_csv('data/drinks.csv')
    选择所有数值型的列
    drinks.select_dtypes(include=['number']).head()
    选择所有字符型的列
    drinks.select_dtypes(include=['object']).head()
    drinks.select_dtypes(include=['number','object','category','datetime']).head()
    用 exclude 关键字排除指定的数据类型
    drinks.select_dtypes(exclude=['number']).head()
  • 根据最大的类别筛选 DataFrame
    movies = pd.read_csv('data/imdb_1000.csv')
    counts = movies.genre.value_counts()
    movies[movies.genre.isin(counts.nlargest(3).index)].head()
  • 基于字符串的长度来筛选数据
    df[df.col1.str.len() > 20].head()
  • 标注重点
    df_new.style.highlight_max(axis = 0, color = "yellow")

五、数值操作

df[‘年龄’].replace(100,33)#对年龄列中的100替换成33
df.replace(np.NaN,0)#相当于fillna(),其中np.NaN是python中缺省值的表示方式
df.replace([A,B],C)#多对一替换,A、B替换成C
df.replace({‘A’:’a’,‘B’:’b’,‘C’:’c’})#多对多替换
df.sort_values(by=['申请单编号'],ascending=False)#申请单编号列降序排列,Ture升序排列(默认)
df.sort_values(by=['申请单编号'],na_position=’first’)#申请单编号列升序排列,缺失值排在第一位
默认缺失值在最后一位last
df = pd.DataFrame([['A',1],['A',3],['A',2],['B',5],['B',9]], columns = ['name','score'])
df.sort_values(['name','score'], ascending = [True,False])#多列排序
df.groupby('name').apply(lambda x: x.sort_values('score',ascending=False)).reset_index(drop=True)

  • Pct_change是一个统计函数,用于表示当前元素与前面元素的相差百分比,两元素的区间可以调整。
    比如说给定三个元素[2,3,6],计算相差百分比后得到[NaN, 0.5, 1.0],从第一个元素到第二个元素增加50%,从第二个元素到第三个元素增加100%。
    DataFrame.pct_change(periods=1, fill_method=‘pad’, limit=None, freq=None, **kwargs)
    periods:间隔区间,即步长
    fill_method:处理空值的方法
    对df的value_1列进行增长率的计算:df.value_1.pct_change()

df[‘销量’].rank(method=’first’)#销量排名(不是排序),method有first\min\max\average

  • pandas 进行组内排序、单组排序、标号
    组内进行排序(按user_id分组后对product_id排序)
    data1['group_sort']=data1['product_id'].groupby(data1['user_id']).rank(ascending=1,method='first')

df.drop([‘销量’,’ID’],axis=1)#删除列,直接是列名,inpace=True是保留修改哦
df.drop(df.columns[[4,5]],axis=1)#删除列,是编号
df.drop(colums=[‘销量’,’ID’])#此种方式删除列,可以不写axis=1
df.drop([‘a’,’b’],axis=0)#删除行,直接是列名
df.drop(df.index[[4,5]],axis=0)#删除行,是编号
df.drop(index=[‘a’,’b’])#此种方式删除行,可以不写axis=0
df[‘ID’].value_counts()#对ID列中数据出现的次数进行统计
df[‘ID’].value_counts(normalize=Ture,sort=False)#对ID列中数据出现的次数占比进行统计,并降序排序
df[‘ID’].unique()#获取列的唯一值
df[‘年龄’].isin([‘a’,11])#查看这列中是否包含a或11
pd.cut(df[‘ID’],bins=[0,3,6,10])#用bins指明切分区间
pd.qcut(df[‘ID’],3)#ID列切分成3个部分,每部分数据个数尽量一致
df.insert(2,’商品’,[‘书’,’笔’,’计算器’])#插入第三列
df[’商品’]=[‘书’,’笔’,’计算器’])#插新列,在表的最后面
df.T行列互换
df.tack()#把表格型数据转化成树形数据
df.set_index([‘ID’,’姓名’]).stack().reset_index()#宽表转换成长表,先将共同列设置成行索引,再对其他列
进行转化成树形数据,再重置行索引

  • 堆叠:pd.DataFrame.stack(self, level=-1, dropna=True),level默认为-1是将最内层col堆叠为索引的最内层,为0是将最外层col堆叠为索引的最内层,从最外层开始依次的level值为0,1,2...的顺序来指定对应col。当然直接指定索引名称或许是更好的选择。

  • 反堆叠、拆堆:pd.DataFrame.unstack(self, level=-1, fill_value=None),默认将最内层的索引拆堆到列的最内层,其他同理stack();

  • df.melt(id_vars=[‘ID’,’姓名’],var_name=’year’,value_name=’sale’)
    id_var参数指明宽表转换成长表时保持不变的列,var_name参数表示原来的列索引转化为行索引对应的列名,value_name表示新索引对应值的列名
    df[‘C1’].apply(lambda x:x+1)#相当于map(),只是需要和lambda配合
    df.applymap(lambda x:x+1),对表中的所有数据执行相同函数运算

  • apply搭配匿名函数lambda的神奇用法:
    df['数据3'] = df.apply(lambda x:(x.数据1-x.数据2)/x.上月 if x.col3!=0 else 0 ,axis=1)

  • 删除包含特定字符串所在的
    行:df['b'].values.astype('str') 先转为字符串格式最好;
    df[df['b'].str.contains('exp',na=False)]

  • 计算变量缺失率
    def missing_cal(df):
    """
    df :数据集
    return:每个变量的缺失率
    """
    missing_series = df.isnull().sum()/df.shape[0]
    missing_df = pd.DataFrame(missing_series).reset_index()
    missing_df = missing_df.rename(columns={'index':'col',
    0:'missing_pct'})
    missing_df = missing_df.sort_values('missing_pct',ascending=False).reset_index(drop=True)
    return missing_df
    missing_cal(df)
    如果需要计算样本的缺失率分布,只要加上参数axis=1。

六、数据运算

df[‘ID’]+Df[‘ID’]#可进行加减乘除
df[‘ID’]>Df[‘ID’]#可进行> < == !=等比较运算
df.nunique()#统计每列不重复值的个数
df.count()#统计每列的非空值的个数
df.count(axis=1)#统计每行的非空值的个数
df[‘ID’].count()#统计指定列的非空值的个数
df.sum(axis=1)#每列/行求和结果
df.mean(axis=1)#每列/行求均值
df.max(axis=1)#每列/行求最大值
df.min(axis=1)#每列/行求最小值
df.median(axis=1)#每列/行求中间值
df.mode(axis=1)#每列/行中出现最多的值
df.var(axis=1)#每列/行求方差
df.std(axis=1)#每列/行求标准差
df.quantile(0.25)#求1/4分位数,可以0.5、0.75等分位数
df.corr()#求整个DataFrame表中的相关性

七、时间序列

from datetime import datetime
datatime.now()#返回现在的时间年月日时分秒
datatime.now().year#返回年,可以.month.day
datatime.now().weekday()-1#返回周几
datatime.now().isocalendar()#返回周数
(2018,41,7)#2018年的第41周第7天
datatime.now().date()#只返回年月日
datatime.now().time()#只返回时间
datatime.now().strftime(‘%Y-%m-%d %H:%M:%S’)#返回2020-03-13 09:09:12
pd.to_datetime(['201221'],format = "%Y%m%d")#返回DatetimeIndex(['2012-02-01'], dtype='datetime64[ns]', freq=None)
pd.to_datetime('201221',format = "%Y%m%d")#不加列表,返回Timestamp('2012-02-01 00:00:00'),需要省去时分秒可以在后面加.strftime("%Y-%m-%d")
from dateutil.parser import parse
parse(str_time)#将字符串的时间转化成为时间格式
pd.Datetimeindex([‘2020-02-03’,2020-03-05’])#设置时间索引
data[‘2018’]#获取2018年的数据
data[‘2018-01’]#获取2018年1月的数据
data[‘2018-01-05’:‘2018-01-15’]#获取这个时段的数据
非时间索引的表格处理
df[df[‘成交时间’]==datetime(2018,08,05)]
df[df[‘成交时间’]>datetime(2018,08,05)]
df[(df[‘成交时间’]>datetime(2018,08,05))&(df[‘成交时间’] <datetime(2018,08,15))]
cha=datatime(2018,5,21,19,50)-datatime(2018,5,18,17,50)
cha.days#返回天的时间差
cha.seconds#返回秒的时间差
cha.seconds/3600#返回小时的时间差
datatime(2018,5,21,19,50)+timedelta(days=1)#往后移一天
datatime(2018,5,21,19,50)+timedelta(seconds=20)#往后移20秒
datatime(2018,5,21,19,50)-timedelta(days=1)#往前移一天

日期时间类型接口一览表

df = generate_sample_data_datetime().reset_index()
df = df.sample(500)
df["Year"] = df["index"].dt.year
df["Month"] = df["index"].dt.month
df["Day"] = df["index"].dt.day
df["Hour"] = df["index"].dt.hour
df["Minute"] = df["index"].dt.minute
df["Second"] = df["index"].dt.second
df["Nanosecond"] = df["index"].dt.nanosecond
df["Date"] = df["index"].dt.date
df["Time"] = df["index"].dt.time
df["Time_Time_Zone"] = df["index"].dt.timetz
df["Day_Of_Year"] = df["index"].dt.dayofyear
df["Week_Of_Year"] = df["index"].dt.weekofyear
df["Week"] = df["index"].dt.week
df["Day_Of_week"] = df["index"].dt.dayofweek
df["Week_Day"] = df["index"].dt.weekday
df["Week_Day_Name"] = df["index"].dt.weekday_name
df["Quarter"] = df["index"].dt.quarter
df["Days_In_Month"] = df["index"].dt.days_in_month
df["Is_Month_Start"] = df["index"].dt.is_month_start
df["Is_Month_End"] = df["index"].dt.is_month_end
df["Is_Quarter_Start"] = df["index"].dt.is_quarter_start
df["Is_Quarter_End"] = df["index"].dt.is_quarter_end
df["Is_Leap_Year"] = df["index"].dt.is_leap_year

八、数据透视表

df.groupby(‘客户分类’).count()#客户分类后求数运算
df.groupby(‘客户分类’).sum()#客户分类后求和运算
df.groupby(‘客户分类’,’区域分类’).sum()#多列分类后求和运算
df.groupby(‘客户分类’,’区域分类’)[‘ID’].sum()#多列分类后ID求和运算
df[‘ID’]#DataFrame取出一列就是Series类型
df.groupby(df[‘ID’]).sum() 相当于 df.groupby(‘ID’).sum()
df.groupby(‘客户分类’).aggregate([‘sum’,’count’]# aggregate可实现多种汇总方式
df.groupby(‘客户分类’).aggregate({‘ID’:‘count’,’销量’: ‘sum’})

  • 用多个函数聚合
    df.groupby('order_id').item_price.agg(['sum','count']).head()
  • aggregate可针对不同列做不同的汇总运算
    df.groupby(‘客户分类’).sum().reset_index()#分组汇总后再重置索引,变为标准DataFrame
    pd.pivot_table(data,values,index,columms,aggfunc,fill_value,margins,dropna,margins_name)
    数据透视表,data:数据表df,values:值,index:行索引,columns:列索引,aggfunc:values的计算类型,fill_value:对空值的填充方式;margins:是否有合计列;margins_name:合计列的列名
    pd.pivot_table(df,values=[’ID’,‘销量’],index=’客户分类’,columms=‘区域’,aggfunc={‘ID’:‘count’,’销量’:‘sum’}),fill_value=0,margins=Ture,dropna=None,margins_name=’总计’)
  • 分组聚合 dict(list(df.groupby('key1')))
    通过字典或Series进行分组
    people = pd.DataFrame(np.random.randn(5, 5),columns=['a', 'b', 'c', 'd', 'e'],index=['Joe', 'Steve', 'Wes', 'Jim', 'Travis'])
    mapping = {'a':'red', 'b':'red', 'c':'blue', 'd':'blue', 'e':'red', 'f':'orange'}
    by_column = people.groupby(mapping, axis=1)
    by_column.sum()

九、多表格拼接

pd.merge(df1,df2)#默认自动寻找两个表中的公共列进行拼接
pd.merge(df1,df2,on=“学号“)#on来指定连接列,连接列要是公共列
pd.merge(df1,df2,on=[‘学号’,’姓名’]#on来指定连接列,连接列要是公共列
pd.merge(df1,df2,left_on=‘学号’right_on=’编号’) #由公共列,但类名不同时用左右键指定
pd.merge(df1,df2,left_index=‘学号’right_index=’编号’)#两表公共列都是索引列时
pd.merge(df1,df2,left_index=‘学号’right_on=’编号’)#公共列一个时索引列一个时普通列
pd.merge(df1,df2,on=’学号’,how=’inner’)#返回公共列中对应的公共值拼接(内连接)
pd.merge(df1,df2,on=’学号’,how=’left’)#返回公共列中对应的左表值(左连接)
pd.merge(df1,df2,on=’学号’,how=’right’)#返回公共列中对应的右表值(右连接)
pd.merge(df1,df2,on=’学号’,how=’outer’)#返回公共列中对应的所有值(外连接)
pd.concat([df1,df2])#两个结构相同的表纵向连接,保留原索引值
pd.concat([df1,df2],ignore_index=True)#两个结构相同的表纵向连接,重新设置索引值
pd.concat([df1,df2],ignore_index=True).drop_duplicates()#拼接后去掉重复值

十、导出文件

df.to_excel(excel_writer=r’C:\users\zhoulifu\Desktop\测试.xlsx’,sheet_name=’文档’,index=False,columns=[‘ID’,’销量’,‘姓名’],encoding=’utf-8’,na_rep=0)

  • excel_writer参数指定文件路径,导出时去掉索引,设置导出的列,指定文件编码,na_rep缺失值填充
    writer=pd.ExcelWriter(excelpath,engine=’xlsxwirter’)

导出多个文件至一个文件的多个sheet;

  • 方法1:
writer=pd.ExcelWriter(excelpath,engine='openpyxl',mode='a')
用openpyxl不会删除excel表中原有sheet,更保险!
df1.to_excel(writer,sheet_name=‘表一’,index= False)
writer.save()
writer.close()
  • 方法2:
df = pd.read_excel(path,sheet_name='test3')
#写入到原Excel表中避免清空其他数据
book = openpyxl.load_workbook(path)   #读取你要写入的workbook
#和pd.read_excel() 用于将Dataframe写入excel。xls用xlwt。xlsx用openpyxl
writer = pd.ExcelWriter(path,engine='openpyxl')   
##此时的writer里还只是读写器. 然后将上面读取的book复制给writer  
writer.book = book
#转化为字典的形式
writer.sheets = dict((ws.title, ws) for ws in book.worksheets)#返回一个字典,sheet名和sheet对象组成的键值对
#将data写入writer
df.to_excel(writer,sheet_name="测试",index=False)
writer.save()
writer.close()
  • to_json
    data = df([['a', 'b'], ['c', 'd']], index=['row 1', 'row 2'], columns=['col 1', 'col 2'])
    json_columns = data.to_json(orient = "columns") # 返回结果:
    '{"col 1":{"row 1":"a","row 2":"c"},"col 2":{"row 1":"b","row 2":"d"}}'
    json_split = data.to_json(orient = "split") # 返回结果:
    '{"columns":["col 1","col 2"],"index":["row 1","row 2"],"data":[["a","b"],["c","d"]]}'
    json_records = data.to_json(orient = "records") # 返回结果:
    '[{"col 1":"a","col 2":"b"},{"col 1":"c","col 2":"d"}]'
    json_index = data.to_json(orient = "index") # 返回结果:
    '{"row 1":{"col 1":"a","col 2":"b"},"row 2":{"col 1":"c","col 2":"d"}}'
    json_values = data.to_json(orient = "values") # 返回结果:
    '[["a","b"],["c","d"]]'
    • format()函数,与lambda函数配合,可以设置:四舍五入保留小数位、转化为百分数、添加千位分隔符等
    保留1位小数:df["A"].map(lambda x: format(x, '.1f'))
    设置百分数,并保留2位小数:df["A"].map(lambda x: format(x, '.2%'))
    设置千位分隔,并保留3位小数:df["A"].map(lambda x: format(x, ',.3f'))
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,839评论 6 482
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,543评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 153,116评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,371评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,384评论 5 374
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,111评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,416评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,053评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,558评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,007评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,117评论 1 334
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,756评论 4 324
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,324评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,315评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,539评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,578评论 2 355
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,877评论 2 345

推荐阅读更多精彩内容