• pandas的学习总结


    pandas的学习总结

    作者:csj
    更新时间:2017.12.31

    email:59888745@qq.com

    说明:因内容较多,会不断更新 xxx学习总结;

    回主目录:2017 年学习记录和总结

    1.pandas简介
    2.pandas数据结构
      Series
      DataFrame
      Index
      csv文件读写
    3.常用函数:
      Group by
      Aggregate
      concat
      merge
      join
    etc

    -------------------------------------------------------------------------------------

     1.pandas简介

      pandas是一个专门用于数据分析的python library。
      基于numpy (对ndarray的操作)
      相当于用python做Excel/SQL/R的感觉;
    2.pandas数据结构
      2.1Series:
         是一个一维的数据结构;默认用0到n来作为Series的index,但是我们也可以自己指定index。
      index我们可以把它理解为dict里面的key;
      s=pd.Series([1,'a',2,'b',2,20])
      s2=pd.Series([1,'a',2,'b',2,20],index=[1,2,3,4,5)
      s4=pd.Series([{'a':1,'b':2},name='price'])
      print(s)
      s3=s.append(s2)
      Series就像一个dict,前面定义的index就是用来选择数据的;
      Series的元素可以被赋值;s1[0]=3
      数学运算;s1 + s2,s4 /2,s4 **2, r = 'a' in s4
      s4.median()中位数
      s4.mean()
      s4.max()
      s4.min();s4[s4 >s4.mean()]
      数据缺失:
      使用notnull和isnull两个函数来判空:s4.isnull(),s4.notnull()
      为空的部分,赋上平均值:s4[s4.isnull()]=s4.mean()
      选择数据:s[1],s1[2,3,1],s1[1:],s1[:-1],s1.get('1'),s1[s1 <2],s1[s1.index !=2]

        2.2 DataFrame:
      一个Dataframe就是一张表格,Series表示的是一维数组,Dataframe则是一个二维数组;
      columns的名字和顺序可以指定;
      可以从几个Series构建一个DataFrame;
      可以用一个list of dicts来构建DataFrame;
      data ={'a':[1,2,3],'b':[4,5,6]}
      pd1 = pd.DataFrame(data)
      df = pd.DataFrame(data,coulums=['t','f'],index=['one','tow','three']) #在DataFrame中columns对应的是列,index对应的是行。
      DataFrame元素赋值:
      可以给一整列赋值:df["t"]=400
      给一整行赋值:df["one"]=100
      可以使用loc,iloc选择一行:
      pd1.loc['one'];pd1.iloc['one'];pd1[1:2]
      pd1中加入df:pd1.append(df2);pd1.append(series1)
      pd1中加入一column:pd1['newcol']=200
      df1["t"].loc["one"] = 300
      df1["colname"]='newcolumn'
      df1.columns
      df1.index
      df1.info
      df.index.name = "city"
      df.columns.name = "info"
      使用isin判断价格在[]范围内的:df1["one"].isin([30, 200])
      df1.where(df1["neo"] > 10)
      对于NAN会被上一个记录的值填充上:df1.fillna(method="ffill") df.ffill()
      df.sub((row, axis=1)) 计算其他的数据与row之间的差值
        2.3Index:
      Series时声明index
      针对index进行索引和切片
      DataFrame进行Indexing与Series基本相同:df.loc[row,colu]
         2.4reindex:
      对一个Series或者DataFrame按照新的index顺序进行重排;
      用drop来删除Series和DataFrame中的index

      2.5csv文件读写:
        read_csv
        to_csv
    3.常用函数:
        Group by
        Aggregate
        concat
        merge
        join

     demo数据清洗:

    分析数据问题

    1. 没有列头
    2. 一个列有多个参数
    3. 列数据的单位不统一
    4. 缺失值
    5. 空行
    6. 重复数据
    7. ASCII 字符
    8. 有些列头应该是数据,而不应该是列名参数

    1数据清洗 。检查数据 查看一列的一些基本统计信息:data.columnname.describe() •选择一列:data['columnname'] •选择一列的前几行数据:data['columnsname'][:n] •选择多列:data[['column1','column2']] •Where 条件过滤:data[data['columnname'] > condition]

    。处理缺失数据 。为缺失数据赋值默认值 data.country.fillna('')#(0,mean) •去掉/删除缺失数据行   data.dropna() data.dropna(how='all')删除一整行的值都为 NA   data.drop(thresh=5)删除一整行数据中至少要有 5 个非空值 •去掉/删除缺失率高的列

    •添加默认值 data.country= data.country.fillna('')

    •删除不完整的行 data.drop(axis=0, how='any')

    •删除不完整的列 删除一正列为 NA 的列:data.drop(axis=1, how='all',inplace=True)行的例子中使用了 axis=0,因为如果我们不传

    参数 axis,默认是axis=0 删除任何包含空值的列:data.drop(axis=1, how='any',inplace=True)

    •规范化数据类型 data = pd.read_csv('../data/moive_metadata.csv', dtype={'duration': int})

    •必要的转换 .错别字 •英文单词时大小写的不统一:data['movie_title'].str.upper() •输入了额外的空格:data['movie_title'].str.strip()

    •重命名列名 data = data.rename(columns = {‘title_year’:’release_date’,

    ‘movie_facebook_likes’:’facebook_likes’})

    •保存结果 data.to_csv(‘cleanfile.csv’ encoding=’utf-8’)

    demo: df.head() .没有列头 # 增加列头 column_names= ['id', 'name', 'age',

    'weight','m0006','m0612','m1218','f0006','f0612','f1218'] df = pd.read_csv('../data/patient_heart_rate.csv', names = column_names)

    .一个列有多个参数值,分割成多列 df[['first_name','last_name']] = df['name'].str.split(expand=True) df.drop('name', axis=1, inplace=True)

    .列数据的单位不统一 rows_with_lbs = df['weight'].str.contains('lbs').fillna(False) df[rows_with_lbs] for i,lbs_row in df[rows_with_lbs].iterrows(): weight = int(float(lbs_row['weight'][:-3])/2.2) df.at[i,'weight'] = '{}kgs'.format(weight)

    .缺失值 data.country.fillna('') •删:删除数据缺失的记录(数据清洗- Pandas 清洗“脏”数据(一)/[数据清洗]-Pandas 清洗“脏”数据

    (一)) •赝品:使用合法的初始值替换,数值类型可以使用 0,字符串可以使用空字符串“” •均值:使用当前列的均值 •高频:使用当前列出现频率最高的数据 •源头优化:如果能够和数据收集团队进行沟通,就共同排查问题,寻找解决方案。

    .空行 # 删除全空的行 df.dropna(how='all',inplace=True) df.dropna(how='any',inplace=True) .重复数据 # 删除重复数据行 df.drop_duplicates(['first_name','last_name'],inplace=True)

    .非 ASCII 字符 处理非 ASCII 数据方式有多种 •删除 •替换 •仅仅提示一下

    我们使用删除的方式:

    # 删除非 ASCII 字符 df['first_name'].replace({r'[^x00-x7F]+':''}, regex=True, inplace=True) df['last_name'].replace({r'[^x00-x7F]+':''}, regex=True, inplace=True)

    .有些列头应该是数据,而不应该是列名参数,将多列合并为一列 # 删除没有心率的数据 row_with_dashes = df['puls_rate'].str.contains('-').fillna(False) df.drop(df[row_with_dashes].index, inplace=True)

    import pandas as pd
    # 增加列头
    column_names= ['id', 'name', 'age', 'weight','m0006','m0612','m1218','f0006','f0612','f1218']
    df = pd.read_csv('../data/patient_heart_rate.csv', names = column_names)

    # 切分名字,删除源数据列
    df[['first_name','last_name']] = df['name'].str.split(expand=True)
    df.drop('name', axis=1, inplace=True)

    # 获取 weight 数据列中单位为 lbs 的数据
    rows_with_lbs = df['weight'].str.contains('lbs').fillna(False)
    df[rows_with_lbs]

    #get row data

    df[1:5]

    #get col data

    df['columnsname']

    #get row and col data

    df['columnsname'][1:3
    # 将 lbs 的数据转换为 kgs 数据
    for i,lbs_row in df[rows_with_lbs].iterrows():
    weight = int(float(lbs_row['weight'][:-3])/2.2)
    df.at[i,'weight'] = '{}kgs'.format(weight)

    # 删除全空的行
    df.dropna(how='all',inplace=True)

    # 删除重复数据行
    df.drop_duplicates(['first_name','last_name'],inplace=True)

    # 删除非 ASCII 字符
    df['first_name'].replace({r'[^x00-x7F]+':''}, regex=True, inplace=True)
    df['last_name'].replace({r'[^x00-x7F]+':''}, regex=True, inplace=True)

    # 切分 sex_hour 列为 sex 列和 hour 列
    sorted_columns = ['id','age','weight','first_name','last_name']
    df = pd.melt(df,
    id_vars=sorted_columns,var_name='sex_hour',value_name='puls_rate').sort_values(sorted_columns)
    df[['sex','hour']] = df['sex_hour'].apply(lambda x:pd.Series(([x[:1],'{}-{}'.format(x[1:3],x[3:])])))[[0,1]]
    df.drop('sex_hour', axis=1, inplace=True)

    # 删除没有心率的数据
    row_with_dashes = df['puls_rate'].str.contains('-').fillna(False)
    df.drop(df[row_with_dashes].index,
    inplace=True)

    # 重置索引,不做也没关系,主要是为了看着美观一点
    df = df.reset_index(drop=True)
    print(df)

    ------add 20180110 by 59888745@qq.com--------

    # Demo 1  of pandas 
    # bike project
    # stocks project
    # credit project
    
    import pandas as pd
    import numpy as np
    bikes = pd.read_csv('data/bikes.csv', sep=';', parse_dates=['Date'], encoding='latin1', dayfirst=True, index_col="Date")
    bikes.head()
    #bikes.dropna()
    #bikes.dropna(how='all').head()
    df0= bikes.dropna(axis = 1,how='all').head()
    bikes.shape
    
    #apply(func, axis=0, broadcast=False, raw=False, reduce=None, args=(), **kwds) method of pandas.core.frame.DataFrame instance
    #apply这个函数可以逐行的来处理内容。 
    #获得每列的有多少行是空的
    #bikes.apply(lambda x:sum(x.isnull()))
    bikes.isnull().sum()
    
    #如何填充缺失的数据
    # row =bikes.iloc[0].copy
    # bikes.fillna(row)
    
    # 得到一列,这一列都是其他行的平均数
    m = bikes.mean(axis=1)
    #然后使用m去一行一行的填充bikes中数据为NaN的
    #bikes.iloc[:, i]表示bikes所有行的第i列。
    for i, col in enumerate(bikes):
        bikes.iloc[:, i] = bikes.iloc[:, i].fillna(m)
        
    bikes.head()
    
    #计算berri_bikes周一到周日中每天分别的骑车的人数进行统计。然后画个图
    berri_bkies=bikes['Berri 1'].copy()
    berri_bkies.head()
    # berri_bkies.index
    # l=berri_bkies.index.weekday 
     
    # berri_bkies["weekday"]=l
    # weekday_counts = berri_bkies.groupby('weekday').aggregate(sum)
    # weekday_counts
    #weekday_counts = berri_bkies.groupby('weekday').aggregate(sum)
    #weekday_counts.index = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday']
    #weekday_counts
    #berri_bkies.plot(kind="bar")
    
    # to_frame可以把一个Series转换成一个DataFrame
    #bikes.sum(axis=1)将每天中所有的线路加在一起
    #berri_bkies.sum(axis=1).to_frame().head()
    
    #Demo 2 
    
        # goog = pd.read_csv("data/GOOG.csv", index_col=0)
        # goog.index = pd.to_datetime(goog.index)
        # goog["Adj Close"].plot(grid = True)
    
        # goog.shift(1).head() #shift其实就是将日期数字往后移动了一天
    
        # aapl = pd.read_csv("data/AAPL.csv", index_col=0)
        # aapl.index = pd.to_datetime(aapl.index)
        # #aapl.head()
        # aapl["Adj Close"].plot(grid=True)
    
    
    #Demo 3
        # df = pd.read_csv("data/credit-data.csv")
        # df.head()
        # for i, val in enumerate(df):
        #     print(val)
        #     print(df[val].value_counts())
    
        # df['income_bins'] = pd.cut(df.monthly_income, bins=15, labels=False)
        # pd.value_counts(df.income_bins)
    
        # df["monthly_income"] = df["monthly_income"].fillna(df["monthly_income"].mean())
    
        # df["income_bins"] = df["income_bins"].astype("int")
    
        
    #pandas cont list 
    
    # Series
        # #构造和初始化Series
        # s = pd.Series({"bj":100,"sz":200})
        # s['bj']
        # s2=pd.Series([1,2,3,4])
        # s2[0]
        # s3=pd.Series(("1",2,3),index=[1,2,3])
        # s4 = s3.append(s2,ignore_index=True)
        # s4
        # s5 =s4.drop(1)
        # s5
        # s6 =pd.Series(np.random.randn(5),index=['a','b','c','d','e'])
        # s6
        # s7 = pd.Series(np.random.randn(5),index=range(6,11))
        # s7
    
        # #选择Series数据 
        # #使用下标格式
        # s7[6]
        # s7[[6,8]]
        # s7[:-1]
        # s7[1:-1]
        # #相加的时候能找到的相加,找不到的为空
        # s8 =s7[1:] + s7[:-1]
        # #可以使用下标格式或者字典格式来找数据
        # s['bj']
        # s[['bj','sz']]
    
        # t = 'bj' in s
        # t
        # t2 =6 in s8
        # t2
        # t3 =s8.get(7)
        # t3
        # t4 = s8[s8 <8]
        # t4
    
        # s8[s8.index !=9]
    #series的增删改查 
    
    tm=pd.Series({'hefei':1000})
    tm2=pd.Series({'hefei2':2000})
    tm3 = tm.append(tm2)
    tm4 =tm3.drop('hefei')
    'hefei2' in tm4
    tm4.get('hefei2')
    tm3['hefei2']=3000
    tm3
    tm3 / 2
    tm3 **2
    np.log(tm3)
    
    tm5 =tm3+tm2*2
    tm5
    tm5.isnull()
    tm6 =tm5[tm5.isnull()]=tm5.mean()
    tm6
    
    # DataFrame
        # data=['beijin',1000,'shenzhen',2000]
        # df=pd.DataFrame(data,columns=['city'],index=['a','b','c','d'])
        # df.loc['b']
        # data2 = [{"a": 999999, "b": 50000, "c": 1000}, {"a": 99999, "b": 8000, "c": 200}]
        # data3 = [ "a",999999, "b", 50000, "c", 1000]
        # df2= pd.DataFrame(data2,index=['one','two'],columns=['a','b','c'])
        # #df2= pd.DataFrame(data3,index=['one','two','three','four','five','six'],columns=['a'])
        # df3 =df2.drop('c',axis=1)
        # df3
        # df4 =df2.drop('one',axis=0)
        # df4
        # #如何改变列的位置?
        # df5= pd.DataFrame(data2,index=['one','two'],columns=['a','c','b'])
        # df5
        #df.dropna()会删除所有带NA的行
        #df.dropna(how='all').head()删掉全部都是NA的行
         #df.dropna(how='any').head()删掉部fen 都是NA的行
         #若ignore_index=True由于索引存在冲突所以会建立新的索引,若为False,会存在索引相同的情况
        #df3 =df2.append(df_s,ignore_index=True) 
        
        #若要三个Series 能够合并的比较好的一个DataFrame那么它们的行index最好是一样的。  
        # s_product=pd.Series([10.0,12.0,14.0],index=['apple','bear','banana'])
        # s_unit=pd.Series(['kg','kg','kg'],index=['apple','bear','banana'])
        # s_num=pd.Series([100,200,300],index=['apple','bear','banana'])
        # #df = pd.DataFrame({'prices':s_product,'unit':s_unit,'num':s_num},columns=['prices','unit','num'],index=['one','two','three'])
        # df = pd.DataFrame({'prices':s_product,'unit':s_unit,'num':s_num},columns=['num1','prices','unit'])
        # df
        # df2 = pd.DataFrame(s_product,columns=['prices'])
        # df2['num']=100
        # s=['a','b','c']
        # df_s=pd.DataFrame(s)
        # #若ignore_index=True由于索引存在冲突所以会建立新的索引,若为False,会存在索引相同的情况
        # df3 =df2.append(df_s,ignore_index=True) 
        # df3 
        # df3[['prices','num']].loc['0':'1']
        # df3
        # df3['0']=200
        # df3['prices'].loc[3:5]=15
        # df3.prices=0
        # df3.num=200
        # df3.num.loc[0]=1
        # df3
        # df3.shape
        # df3.info
        # df3.describe()
        # df3.prices.value_counts()
    
        # in_prices=pd.Series([100,200,300],index=[0,1,2])
        # df3.prices=in_prices
        # df3
        # df3['remark']= df3.prices >100
        # df3
    
        # df_t=df3.T
        # df_t
        # ss=pd.Series({'prices':0,'num':0,'0':0,'0':0,'remark':0})
        # df_t['hefei']=ss
        # df_t=df_t.T
        # df_t
        # df_t.loc['hefei2']=0
        # #df_t.T
        # df_t.index.name='remark'
        # df_t.columns.name='city'
        # df_t
        # # df5 =df_t['prices'].isin([100,200])
        # df_t.where(df_t['num'] ==200)
    
        # df_t['num'] ==200
        # df_t.fillna(method='ffill')
        # df_t.ffill()
        #df_t.fillna(value=0)
        
    # Index
        #reindex()
    # csv文件读写 
        #goog = pd.read_csv("data/test.csv", index_col=0)  pd.read_csv('data/bikes.csv', encoding='latin1')
        #bikes = pd.read_csv('data/bikes.csv', sep=';', parse_dates=['Date'], encoding='latin1', dayfirst=True, index_col='Date')
        # encoding='latin1':文件解析的时候默认是有utf-8来解析的,所以有时候会出错,要改成'latin1';dayfirst=True表示的是Date排列的时候是按顺序的,
        # index_col='Date' 将Date作为index
    
        #df.to_csv("data/test2.tsv", sep="	")
    
    # date
    #     d1=pd.date_range('20180102',periods=5)#5 is row num
    #     s=np.random.randn(5,4)#5 is row num
    #     df1=pd.DataFrame(s,index=d1,columns=list('abcd'))#columns的名字和顺序可以指定
    # Group by
        #df_grb = df.groupby('name')
        #df_grb.sum()  df_grb.var()  df_grb.mean()  df_grb.describe()
    # Aggregate
        #weekday_counts = berri_bkies.groupby('weekday').aggregate(sum)
    # concat
        #df.concat([df1,df2,df3],axis=1)
        #df.append(df1)
        #df.append([df1,df2])
        
    # merge
        #df.merge(df0,df1,on='cities')
        #df.merge(df0,df1,on='cities',how='outer')   how:left,right,outer
    # join
        #df.join(df0, lsuffix=" goog", rsuffix=" aapl")
    
    #apply(func, axis=0, broadcast=False, raw=False, reduce=None, args=(), **kwds) method of pandas.core.frame.DataFrame instance
        #apply这个函数可以逐行的来处理内容。 
        #获得每列的有多少行是空的
        #df.apply(lambda x: sum(x.isnull()))
        
    #df.isnull().sum()
    #如何填充缺失的数据
        #row = df.iloc[0].copy()
        #row.fillna(row.mean())
    
    # 得到一列,这一列都是其他行的平均数
    #     m = bikes.mean(axis=1)
    #     #然后使用m去一行一行的填充bikes中数据为NaN的
    #     #bikes.iloc[:, i]表示bikes所有行的第i列。
    #     for i, col in enumerate(bikes):
    #         bikes.iloc[:, i] = bikes.iloc[:, i].fillna(m)
    
    #     bikes.head()    
        
    bikes.apply(lambda x: sum(x.isnull()))
    import pandas as pd
    import numpy as np
    #若要三个Series 能够合并的比较好的一个DataFrame那么它们的行index最好是一样的。  
    df = pd.DataFrame({
        'Name': ['a1', 'b1', 'c1', 'd1', 'a1', 'b1', 'c1', 'd1'],
        'Year': [2016,2016,2016,2016,2017,2017,2017,2017],
        'Salary': [10000,2000,4000,5000,18000,25000,3000,4000],
        'Bonus': [3000,1000,1000,1200,4000,2300,500,1000]
    })
    #groupby
    df1= df.groupby('Name').sum()
    df1
    
    Out[61]:
    Date
    2012-01-01     35
    2012-01-02     83
    2012-01-03    135
    2012-01-04    144
    2012-01-05    197
    Name: Berri 1, dtype: int64
    In [ ]:
     
  • 相关阅读:
    Kill Processes in Linux
    How to Setup Chroot SFTP in Linux (Allow Only SFTP, not SSH)
    156 Useful Run Commands
    6
    pandas groupby合并列字符串
    一个ROS配置的脚本
    Mybatis 学习记录
    Android搭建code server
    CF 1616D. Keep the Average High
    第七章:(1)Redis 的发布订阅
  • 原文地址:https://www.cnblogs.com/csj007523/p/8158347.html
Copyright © 2020-2023  润新知