Pandas常用操作以及常见tips、tricks

本站访问次数:

常用操作

读数据

1.读csv

df = pd.read_csv("data.csv")

2.读数据库

import MySQLdb
from pandas import DataFrame
from pandas.io.sql import read_sql
db = MySQLdb.connect(host="localhost",    # your host, usually localhost
                     user="root",         # your username
                     passwd="password",   # your password
                     db="dbname")         # name of the data base
query = "SELECT * FROM tablename"
df = read_sql(query, db)

数据快照

1.使用head和tail命令查看指定行数据

import pandas as pd
df = pd.read_csv("data.csv")
# 返回数据帧的信息,包括行列数,列名,类型,大小等
df.info()

# top 5 rows
df.head()
# top 50 rows
df.head(50)
# last 5 rows
df.tail()
# last 50 rows
df.tail(50)

2.获取数值列的统计信息

df.describe()
# 取列名为num1的列
col = df['num1']
# 打印此列最大值
print(max(col))
# 打印dataframe的行数
print(len(df))
#打印dataframe的Shape
print(df.shape)

处理dataframe中的列

1.选择列. pandas选择列数据的方式有两种,一种是点运算符(比如:df.A),一种是方括号(比如: df[“A”]). 由于列名可能包含空格或者和pandas数据帧内置函数相同或需要列名作为变量时,点运算符的方式失效。故推荐 方括号形式。

# 点运算方式,不能给num1加引号
df.num1
# 方括号方式
col_name  ="num1"
df[col_name]

2.获取列名

columnnames = df.columns

3.指定列名

# 必须保证新列名数和旧列名数量一样
df.columns = ['c1', 'c2', 'c3', 'c4','c5']
# 修改指定的列名
df.rename(columns = {'c1':'R1','c5':'R2'},inplace=True)

4.获取指定列的字集

df = df[['R1', 'R2']]

5.查看列的数据类型

df.dtypes

在数据帧上应用函数:apply和Lambda

1.创建列

# 通过基本算术操作增加列
df['new'] = (df['R1'] + df['R2']/10)/2

# 需要对列数据进行复杂的操作
def custom_fun(date, R1):
    if '2018-01-01' in date:
        return min(10,R1+1)
    elif '2019-01-01' in date:
        return max(0,rating-1)
    else:
        return rating

df['rate'] = df.apply(lambda x: custom_fun(x['date'],x['R1']),axis=1)

# 一般结构如下:
df.apply(lambda x: func(x['col1'],x['col2']),axis=1)

2.过滤数据帧 Pandas可以非常轻松地对数据帧进行过滤和子集化。可以使用常规运算符和&,|,〜运算符对数据帧进行过滤和子集化

# 过滤出R1列大于8的所有数据
df_gt_8 = df[df['R1']>8]
# 过滤出R1列大于8同时date列大于2018-01-01的所有数据
And_df = df[(df['R1']>8) & (df['date']>'2018-01-01')]
# 过滤出R1大于8或者R2大于80的所有数据
Or_df = df[(df['R1']>8) | (df['R2']>80)]
# R1大于8或者R2大于80的所有数据都将被排除
Not_df = df[~((df['R1']>8) | (df['R2']>80))]

# 过滤出c2列以-化为后长度大于3数据
new_df = df[df.apply(lambda x : len(x['c2'].split("-"))>=3,axis=1)]

3.改变列类型

# 在进行数据转换的时候,如果c2中包含不能转换的字符则会报错,如下,希望将日期字符串转化为数字,第一种方式会报错,
# 因为包含‘-’符号,无法转换
df['c2_new'] = newDf['c2'].astype('int')
# 使用apply lambda进行转换
df['Price'] = df.apply(lambda x: int(x['c2'].replace('-', '')),axis=1)

数据帧的聚合

对于groupBy函数,使用格式参考如下。 只需要提供两个主要信息: (1)要分组的列 (2)指定要应用列和对应列的函数字典

df.groupby(list of columns to groupby on).aggregate({'colname':func1, 'colname2':func2}).reset_index()
# 如数据有三个列,分别为date(日期),和数值列,以date分组,计算数值列的和,即计算date为同一天下c1和c2各自的总和
df.groupby(['date']).aggregate({'c1':np.sum, 'c2':np.sum}).reset_index()

多数据帧处理,concat与merge

1.concat. 使用concat对数据帧进行拼接,可通过指定axis设置拼接方式,默认行拼接axis=0(行数增加),axis=1-列拼接(列数增加)

m1 = df[df['c2']=='2018-01']
m2 = df[df['c2']=='2019-01']
# 行数为两者和,列数不变
m3 = pd.concat([m1,m2],axis =0)
# 列数为两者和,行数不变
m4 = pd.concat([m1,m2],axis =1)

2.merge 当信息分布在多个数据帧中时,需要将多个数据帧进行融合(类似数据库中的表连接)

# 对两个数据帧在列名为same_col列进行左连接
df_merge = pd.merge(dataframe1,dataframe2,on='same_col',how='left')

连接方式有:[‘left’,‘right’,‘inner’,‘outer’],大部分时候需要的是左连接

Tips and tricks

  • 很多方法并不会直接修改原dataframe,而是返回修改后的dataframe,如果想要直接修改原dataframe, 设置参数inpalce=True。
  • 以未知的index检索数据:对于海量数据,难以知道某一行的index,如

    #查询ID为1的行所在的index
    indexRequred = data.index[data['id']==1]
    # 检索index为indexRequired行的内容
    rowRequired = data.loc[indexRequred]
    
    • 返回某一列所有不同的属性值: list_of_unique_ids = data[‘id’].unique()

    • 对列填充缺失值:假如存在两列’name’,‘date’,两列存在null值,希望对’name’为null的填充字符串‘lin’,‘date’为null的填充‘2019-08-10’

    missing = {'name':'lin', 'date':'2019-08-10'}
    data.fillna(value = missing, inplace = True)
    
  • 对样本按属性排序:例,取前100行样本,按日期排序

    sample = data.sample(n=1000)
    sorted_sample = sample.sort_values(by=['date'])