提示:这里对文章进行总结:
例如:以上就是今天要讲的内容,本文仅仅简单介绍了pandas的使用,而pandas提供了大量能使我们快速便捷地处理数据的函数和方法。
一维数据结构,数据呈单列,索引为行
import pandas as pd
import numpy as np
s = pd.Series([18,20,25])
pandas会默认用0到n-1来作为Series的index,但是我们也可以自己指定index。index我们可以把它理解为dict里面的key。

s = pd.Series([18,20,25], index = ['张三','李四','王五'])
#等同于上式pd.Series([18,20,25], index = ['张三','李四','王五'])
#本质上Series就是索引键值对
s = pd.Series({
'张三':18,'李四':20,'王五':25})
通过series.to_frame()方法可转为Dataframe
二维数据结构,与Series不同,是带有“行索引”和“列索引”的多列数据。
import pandas as pd
import numpy as np
data = {
'city': ['Beijing', 'Shanghai', 'Guangzhou', 'Shenzhen', 'Hangzhou', 'Chongqing'],
'year': [2016,2017,2016,2017,2016, 2016],
'population': [2100, 2300, 1000, 700, 500, 500]}
pd.DataFrame(data)
frame = pd.DataFrame(data, columns = ['year', 'city', 'population'],
index = ['one', 'two', 'three', 'four', 'five', 'six'])

此外,还有一种定义行数据的方法生成DataFrame,不常使用,不推荐!
df = pd.DataFrame([[22,'Beijing','Lawyer'],[18,'Shanghai','IT'],[25,'Shenzhen','Farmer']],index = ['张三','李四','王五'],columns =['age','city','job'])
pd.set_option('display.max_columns', None)
pd[‘age’] #索引’age’列, 返回pd.serires类型
pd[[‘age’]] #索引’age’列, 返回pd.Dataframe类型
pd.loc[ “行名称”, “列名称”],如pd.loc[ : ,‘age’],返回pd.serires类型
pd.loc[ “行名称”, “列名称”],如pd.loc[ : ,[‘age’]],返回pd.Dataframe类型
Attention! 返回serires和Dataframe这两者之间是有区别的,笔者曾经就吃过亏,当采用方式1或3索引’age’列时,返回的是serires结构,这种结构是不支持dataframe的相关操作,例如如果采用pd[‘new_column’] = 1这种方式新增一列,是行不通的,因为这是dataframe结构的用法。
需采用方式2或4以保持Dataframe结构,才可进行dataframe的相关操作。
| 方法 | 备注 |
|---|---|
| df.drop(’#col’, axis = 1) | #col:待丢弃的列,可以是元素,也可以是list |
| drop_columns = [‘col1’, ‘col2’, ‘col3’], df.drop(drop_columns, axis = 1) | |
| del df[’#col1’] | #col1:不可为list,只能是元素 |
Dataframe结构可以通过df.replace(dict)接口对指定维度(列)进行替换。例如某Dataframe为:

使用df.replace(dict)进行替换,形参以字典形式传入:
df['age'] = df['age'].astype('str')
df['age'] = df['age'].replace({
'-1':0,
'15岁以下':1,
'16-25岁':2,
'26-35岁':3,
'36-45岁':4,
'46-55岁':5,
'56岁以上':6,})
对于时间戳的处理,可采用两种方法:
(一)datetime( )
(1)获取指定的时间和日期。datetime(%Y,%m,%d,%H,%M,%S)
datetime共有6个参数,分别代表的是年月日时分秒。其中年月日是必须要传入的参数,时分秒可以不传入,默认全为零。
(2)字符串与时间的转化strptime / strftime
strptime: 将str转为datetime,这里p是parse,代表分析
strftime: 将datetime格式化为字符串,这里f是format,代表格式化
strptime将字符串转化为datetime类型
dt1 = datetime.datetime.strptime('2021-09-26 00:00:00', '%Y-%m-%d %H:%M:%S')
strftime将datetime类型转化为字符串
datetime.datetime.strftime(dt1, '%Y-%m-%d %H:%M:%S')
在很多情况下,我们的原始数据中的时间和日期并不是时间类型的,例如excel中可能是Unicode,csv中可能是Str。因此我们在进行时间切片之前首先要将非时间类型的时间数据转换为时间类型。
(二)pd.to_datetime( )
pandas中的to_datetime( )有和datetime( )类似的功能。
(1)获取指定的时间和日期。记得要填充format形参。
eg:

(2)将csv文件中的Str和Unicode转化为时间格式,使用strptime方法
eg:
将两个时间相减,求得时间差,转为秒s
df['payback_period_audition'] = (pd.to_datetime(df['audition_create_date']) - pd.to_datetime(df['alloc_create_date'])).dt.total_seconds()
转为天用timestamp.dt.days
目的:将离散型特征的每一种取值都看成一种状态
pandas.get_dummies(data, prefix=None, prefix_sep=’_’, dummy_na=False, columns=None, sparse=False, drop_first=False)
| 参数 | 备注 |
|---|---|
| prefix | get_dummies处理后,列名的前缀 |
例如某dataframe为下图所示:

讲离散变量’user_lv_cd’处理为独热向量,映射到欧氏空间,然后与原数据合并
dummy_col = pd.get_dummies(df['user_lv_cd'])
df = pd.concat([df,dummy_col], axis = 1)
| 读入csv | df = pd.read_csv(FILE_PATH) 若csv首行没有特征名,可以通过names=[]的方式给列添加特征名 |
| 若缺失特征名时1 | 当读入csv后,发现缺失特征行,可以通过添加header=None的方式增加特征行,然后df.columns=[xxxx]重命名特征行, df = pd.read_csv(FILE_PATH,header=None), df.columns=[xxxx] |
| 若缺失特征名时2 | 也可以直接通过pd.read_csv(FILE_PATH, header=None, names=[xxxx])构建 |
| df = pd.read_csv(FILE_PATH, skiprows = 1), 跳过1行,即跳过首行 | |
| df = pd.read_csv(FILE_PATH, skiprows = [0,1]), 跳过索引[0,1]行 | |
| df = pd.read_csv(FILE_PATH, skipfooter = 1), 跳过尾行,类似skiprows | |
| 写入csv | df.to_csv(FILE_PATH) ;注意,to_csv是dataframe的方法 |
跳行操作可参考此文章
[https://blog.csdn.net/weixin_44936542/article/details/89418691]
今天在读取一个超大csv文件的时候,遇到困难:
首先使用office打不开
然后在python中使用基本的pandas.read_csv打开文件时:MemoryError
最后查阅read_csv文档发现可以分块读取。
指定iterator=True 也可以返回一个可迭代对象TextFileReader :
reader = pd.read_csv(ACTION_FILE, iterator=True) #iterator=True,开启分块提取数据
chunk = reader.get_chunk(chunk_size) #每次读取chunk_size大小的数据,这样便可预先观察数据的前几行
若使用此方法提取完整数据,可参考
reader = pd.read_csv(ACTION_FILE, iterator=True) #iterator=True,开启分块提取数据
chunks = []
loop = True
while loop:
try:
chunk = reader.get_chunk(chunk_size) #每次读取chunk_size = 10000大小的数据
chunk = chunk[(chunk.time >= start_date) & (chunk.time < end_date)][field] #先选出符合时间条件的数据,再选出相应的特征
chunks.append(chunk)
except StopIteration:
loop = False
print('Iteration is stopped.')
df = pd.concat(chunks, ignore_index=True)
pickle.dump(df, open(dump_path, 'wb'))
In [3]: df
Out[3]:
colA colB colC colD
0 A A 100 100
1 A A 100 100
2 B B 30 60
3 C D 50 80
4 A A 20 50
| df.drop_duplicates() | 按全量字段去重, 保留第一个(默认) |
In [4]: df2 = df.drop_duplicates()
In [5]: df2
Out[5]:
colA colB colC colD
0 A A 100 100
2 B B 30 60
3 C D 50 80
4 A A 20 50
| df.drop_duplicates(subset=[‘colA’, ‘colB’], keep=‘first’) | 按指定字段去重, 保留第一个 |
In [6]: df3 = df.drop_duplicates(subset=['colA', 'colB'], keep='first');df3
Out[6]:
colA colB colC colD
0 A A 100 100
2 B B 30 60
3 C D 50 80
| df.drop(index=index, inplace=True) | 丢弃指定index的行 |
常结合for index, row in df.iterrows()进行操作,遍历到需要丢弃的行时,直接利用当下的index进行丢弃,如下所示:
for index, row in df.iterrows():
_min_alloc_create_date = df[df['clue_code'] == row['clue_code']]['alloc_create_date'].min()
_order_create_date = row['audition_create_date']
if _order_create_date < _min_alloc_create_date:
idx.append(row['id'])
df.drop(index=index, inplace=True)
df = df1[df1.col1.isin(df2.col1)]
例如,df1-df2(将df1中去掉df2的数据)
set_diff_df = pd.concat([df1, df2, df2]).drop_duplicates(keep=False)
# 将df中时间区间在4-28和6-12之间,且saler_type==1的数据剔除
_sub_df = df[(df['create_date'] > '2021-04-28 00:00:00') & (df['create_date'] < '2021-06-12 00:00:00')]
_sub_df = _sub_df[_sub_df['saler_type'] == 1]
df = pd.concat([df, _sub_df, _sub_df]).drop_duplicates(keep=False)
1.利用df.duplicated(keep=False)提取重复的item
keep=False代表保留所有的样本,默认keep=First,这样会导致两个重复数据,第一个不被认为重复。

duplicate = df.duplicated(subset='col1',keep=False) # 只提取col1列的重复数据
df[duplicate]
对于某些分类型模型,需要对连续值进行分箱处理,根据设定的阈值将连续值分类。
比如存在某一df

我们需要根据col1的值来进行分箱处理,处于(0,5]区间的认为是A类,处于(5,10]区间的认为是B类,区间是左闭右开的。
df['label'] = pd.cut(df['col1'], bins=[-1,5,10], labels=['A','B'])
# bins左端选择-1是因为,区间是左闭右开的,因此要把0囊括进来,就需要初始左端为-1
df若根据某一特征取最小的20个样本,可调用此接口
df.nsmallest(columns='age', n=20)
同理,df若根据某一特征取最大的20个样本,可调用此接口
df.nlargest(columns='age', n=20)
注意,多筛选条件要用&不要用and,因为and返回的是True/False
df1[(df1[‘col1’]==2) & (df1[‘date’]>‘2021-09-04 00:00:00’)]
或条件用’|’
df1[(df1[‘col1’]==2) | (df1[‘date’]>‘2021-09-04 00:00:00’)]