引言:最近pandas好久不用忘光光先写一点备着,以后实时更新防止自己忘掉,都是pandas最基本的概念,但是和别的博客有点不同,里面有着大量的实例可以帮助大家更好的理解pandas库的各个函数而不是枯燥的概念
pandas常用操作
- 前期准备
- 文件读取和保存
-
- 普通保存
- 类型切换保存
- 保存时的设置参数
- 大文件读取
- 分类型读取
- 数据处理
-
- 数据前期预处理
- 数据后期预处理(哑标,大小写,随机重排序)
- 数据类型转换
- 数据选取
- 数据切割划分
- 数据缺失
- 数据填充
- 数据去重
- 数据替换
- 数据分组
- 数据聚合
- 数据规整
-
- 数据合并连接
- 数据索引分层
- 重命名轴索引
- 数据排序
- apply和map和lambda函数
- 时间处理
-
- 时间序列基础
- 日期解析和提取
- 时区转换
- 正则表达式
- 另外一些函数(sum,count,add,fill)
- 典型筛选案例
-
- 自定义函数
- 函数组合
- 其他(重采样,take,data-dict转换等)
- numpy基础
前期准备 这里先提供一组数据集
data = https://www.it610.com/article/{'state':['Ohio2','Ohio2','Ohio2','Nevada2','Nevada2'],
'year':[2002,2012,2022,2012,2022],
'pop':[1.52,1.72,3.62,2.42,2.92],
'salary':['5000K/MTH - 20000K/MTH', '12K/MTH - 19K/MTH',
'4000K/MTH - 6000K/MTH', '14000K/MTH - 22000K/MTH','8000K/MTH - 20000K/MTH']
}
data = https://www.it610.com/article/pd.DataFrame(data)
文件读取和保存 普通保存
#读取
data = https://www.it610.com/article/pd.read_csv(r'E:\vscode_code\练习\文本练习\东方火锅.csv')#保存,这里保存为txt模式,所以参数要稍微变化
#显示以制表符分割,否则保存就是按照csv模式的逗号分割而不是txt的制表符分割
data.to_csv(r'E:\vscode_code\练习\文本练习\1.txt', sep = '\t', index = False)
#普通的csv保存不需要制表符分割,因为他本身是以逗号进行分割
data.to_csv(r'E:\vscode_code\练习\文本练习\1.csv', index = False)
类型切换保存
#Excel文件
data = https://www.it610.com/article/pd.read_excel(r'E:\vscode_code\数据分析第二版\数据保存\文件测试\test.xlsx','Sheet1',index_col=0)
#保存为csv
data.to_csv(r'E:\vscode_code\数据分析第二版\数据保存\文件测试\test.csv',encoding='utf-8')
#这个时候一定要加'header=None', 这样读进来的列名就是系统默认的0,1,2... 序列号,不然会把文件内容当做列名
data = https://www.it610.com/article/pd.read_csv(r'E:\vscode_code\数据分析第二版\数据保存\文件测试\test.csv', header=None)
保存时的设置参数
#第一: 一定要使用header = false, 不然的话保存数据集的时候,会自动使用0-n作为数据的列名。但如果是字典,就使用键值当索引
#第二: 一定也要使用index=False, 不然的话保存数据的时候,会自动加上一个索引列。
#第三: 如果不需要覆盖原文件, 用mode='a',默认是覆盖原文件的
#这里因为是字典带有键值,所以还是header=true,但是如果需要data.to_csv(r'E:\vscode_code\数据分析第二版\数据保存\1.csv', index=False, header=True)
data2.to_csv(r'E:\vscode_code\数据分析第二版\数据保存\1.csv', index=False, mode='a', header=False)
data3.to_csv(r'E:\vscode_code\数据分析第二版\数据保存\1.csv', index=False, mode='a', header=False)
大文件读取 在python中使用基本的pandas.read_csv打开文件时:MemoryError
import pandas as pd def knn():
#创建一个新的dataframe数据,用来append
frame = pd.DataFrame()
# 读取数据
file_path = r'E:\vscode_code\多线程\双色球\qiu2.csv'reader = pd.read_csv(file_path, chunksize=20)# 每块为20条数据(index)for chunk in reader:
#这里需要重新设置索引,不然索引可能会重复
frame = frame.append(chunk).reset_index(drop=True)
#print(chunk.head())
#只输出一块,把这个去掉就是所有数据了
#break
print(frame.describe())
if __name__ == '__main__':
knn()
分类型读取
df=pd.read_csv('text.csv', dtype={'code':str}
'''
这样,把你要转换的列的名字设定好, “code”列中的数据读取为str
这样,读取到的数据就是按照我们的要求的了。否则,类似001会读取成为1
'''
数据处理 数据前期预处理
#输出文件类型
print(data.info())#输出所包含的不重复内容
print(data['year'].unique())#数据的答题内容包含列名和数据个数
#但是这里经过测试,只有数字类型的才会被统计
print(data.describe())#默认前五个输出
print(data.head())#默认后五个输出
print(data.tail())#其他
data.index
data.columns
data.values#注意点
sdata = https://www.it610.com/article/{'Ohio': 35000, 'Texas': 71000, 'Oregon': 16000, 'Utah': 5000}
obj3 = pd.Series(sdata)
#单个元素的字典直接转为DataFrame时,程序会报错,需要适当做些转换,指定行索引或者列索引才行
#sdata2 = {'Ohio': [35000], 'Texas': [71000], 'Oregon': [16000], 'Utah': [5000]}
#obj4 = pd.DataFrame(sdata2)
#print(obj3)
#print(obj4)
states = ['California', 'Ohio', 'Oregon', 'Texas']
obj4 = pd.Series(sdata, index=states)
数据后期预处理(哑标,大小写,随机重排序)
data = https://www.it610.com/article/pd.DataFrame({'food': ['bacon', 'pulled pork', 'bacon',
'Pastrami', 'corned beef', 'Bacon',
'pastrami', 'honey ham', 'nova lox'],
'ounces': [4, 3, 12, 6, 7.5, 8, 3, 5, 6]})
#把他全部转化为小写字母
lowercased = data['food'].str.lower()#通过需要排列的轴的长度调用permutation,可产生一个表示新顺序的整数数组:(permuting,随机重排序)
samper = np.random.permutation(5)
print(samper)
#take函数用以获取对应索引的信息
df.take(samper)#计算指标/哑变量#########################################
#将分类变量(categorical variable)转换为“哑变量”或“指标矩阵”。
df = pd.DataFrame({'key': ['b', 'b', 'a', 'c', 'a', 'b'],
'data1': range(6)})
#print(df)
#print(pd.get_dummies(df['key']))#给指标DataFrame的列加上一个前缀,以便能够跟其他数据进行合并
dummies = pd.get_dummies(df['key'], prefix='key')
#print(dummies)
数据类型转换
data = https://www.it610.com/article/{'a':['1','2','3'],'b':['4','5','6']}
data = https://www.it610.com/article/pd.DataFrame(data)
#print(data)#这是修改两种数据类型的方法
pd.to_numeric(data['a'], errors='coerce')
print(type(data.iloc[0,1]))
#必须要经过赋值才能够实现
data['c'] = pd.to_numeric(data['a'], errors='coerce')
print(data.iloc[2,2])
print(type(data.iloc[2,2]))
data['b'] = data['b'].astype('int64')
print(data.iloc[2,1])
print(type(data.iloc[2,1]))
数据选取
import pandas as pd
import numpy as np '''
iloc主要使用数字来索引数据,而不能使用字符型的标签来索引数据。
而loc则刚好相反,只能使用字符型标签来索引数据,不能使用数字来索引数据,
不过有特殊情况,当数据框dataframe的行标签或者列标签为数字,loc就可以来其来索引。
''' df=pd.DataFrame(np.arange(0,60,2).reshape(10,3),columns=list('abc'))
print(df.loc[0,['a', 'b']])data = https://www.it610.com/article/{'state':['Ohio1','Ohio1','Ohio2','Nevada3','Nevada3'],
'year':[2000,2001,2002,2001,2002],
'pop':[1.5,1.7,3.6,2.4,2.9],
'salary':['1000K/MTH - 20000K/MTH', '7K/MTH - 8K/MTH',
'10000K/MTH - 16000K/MTH', '3K/MTH - 5K/MTH', '7K/MTH - 12K/MTH',]
}
data = https://www.it610.com/article/pd.DataFrame(data)
#报错原因:https://blog.csdn.net/niuniuyuh/article/details/76650904
#print(data.loc[0,1])
#print(data.loc[:,[0,3]])
#print(data.iloc[0:3,'state'])
print(data.loc[0:3,'state'])
print(data.iloc[0:3,0:3])
print(data.iloc[:,[0,3]])
#print(data.iloc([0,3]))这句是错的,因为参数没有指定完全data.index = ['a','b','c','d','e']
#报错原因:https://blog.csdn.net/niuniuyuh/article/details/76650904
#print(data.loc[0:3,'state'])
print(data.loc['a'])
print(data.loc[['a','b'], 'state'])#索引的其他用法################################3
#这两个索引函数也适用于一个标签或多个标签的切片:
#print(data.loc[:'Utah', 'two'])
#上下两种用法一样
#print(data.iloc[:, :3][data.three > 5])
#print(data.iloc[:, :3][data['three']>5])#pandas可以对不同索引的对象进行算术运算。在将对象相加时,如果存在不同的索引对,则结果的索引就是该索引对的并集。
s1 = pd.Series([7.3, -2.5, '', 1.5], index=['a', 'c', 'd', 'e'])
s2 = pd.Series([-2.1, 3.6, -1.5, 4, 3.1],index=['a', 'c', 'e', 'f', 'g'])
#print(s1 + s2)
数据切割划分
#离散化和面元划分#############################
ages = [20, 22, 25, 27, 21, 23, 37, 31, 61, 45, 41, 32]
bins = [18, 25, 35, 60, 100]
cats = pd.cut(ages,bins)
#print(pd.value_counts(cats))
#你可以通过传递一个列表或数组到labels,设置自己的面元名称:
group_names = ['Youth', 'YoungAdult', 'MiddleAged', 'Senior']
pd.cut(ages, bins, labels=group_names)
#qcut是一个非常类似于cut的函数,它可以根据样本分位数对数据进行面元划分。
数据缺失
data.drop(data[data['标题'].isnull()].index, inplace = True)#若原处是空字符串还需要用np.nan替换,因为dropna只对np.nan处理
data.replace(to_replace=r'',value=https://www.it610.com/article/np.nan,regex=True,inplace=True)
#注意下面两种的区别,第一个只对某一列处理,整体没变
data['标题'].dropna(axis = 0, inplace = True)
#第二个才是对整体的处理
data.dropna(axis = 0,subset = ['标题'], inplace = True)
#传入how='all'将只丢弃全为NA的那些行:
data.dropna(how='all')
数据填充
#填充################################
data.fillna(0)
#若是通过一个字典调用fillna,就可以实现对不同的列填充不同的值:
data.fillna({1: 0.5, 2: 0})
#默认返回新对象,若对现有对象修改,用inplace参数
data.fillna(0, inplace=True)
#里面还有别的参数可以了解
数据去重
#去重
#输出的只有state这一列
print(frame['state'].duplicated())
print(frame['state'].drop_duplicates())#输出的是经过去重后所有的数据
print(frame.drop_duplicates(['state']))
#保留最后一个
print(frame.drop_duplicates(['state'], keep='last'))
数据替换
#替换
#可以用字典对多个值进行替换
frame['year'].replace({2002:'1', 2012:'2'}, inplace=True)
frame['state'].replace({'Ohio2':'1', 'Nevada2':'2'}, inplace=True)#替换#################################
#map可用于修改对象的数据子集,而replace则提供了一种实现该功能的更简单、更灵活的方式
data = https://www.it610.com/article/pd.Series([1., -999., 2., -999., -1000., 3.])
#一次性替换多个值,可以传入一个由待替换值组成的列表以及一个替换值
data.replace([-999, -1000], np.nan)
#要让每个值有不同的替换值,可以传递一个替换列表:
data.replace([-999, -1000], [np.nan, 0])
#传入的参数也可以是字典:
data.replace({-999: np.nan, -1000: 0})#针对csv的replace需要先转化成str
print(data['标题链接'].str.replace('www', '').head())
数据分组
import pandas as pd
import numpy as npdf = pd.DataFrame({'key1' : ['a', 'a', 'b', 'b', 'a'],
'key2' : ['one', 'two', 'one', 'two', 'one'],
'data1' : np.random.randn(5),
'data2' : np.random.randn(5)})
#group之后只是一个对象,可以对这个对象进行一系列操作
grouped = df['data1'].groupby(df['key1'])
means = df['key2'].groupby(df['key1'])
count = df['key1'].groupby(df['key2'])
#print(means)states = np.array(['Ohio', 'California', 'California', 'Ohio', 'Ohio'])
#print(df['data1'].groupby([states]).mean())#GroupBy的size方法,任何分组关键词中的缺失值,都会被从结果中除去。
#size跟count的区别: size计数时包含NaN值,而count不包含NaN值
#https://www.cnblogs.com/zknublx/p/12048410.html
print(df.groupby(['key1', 'key2']).size())"""
#GroupBy对象支持迭代,可以产生一组二元元组(由分组名和数据块组成)
for name,group in grouped:
print(name)
print(group)
""" #mapping传递
people = pd.DataFrame(np.random.randn(5, 5),
columns=['a', 'b', 'c', 'd', 'e'],
index=['Joe', 'Steve', 'Wes', 'Jim', 'Travis'])
#你可以计算一个字符串长度的数组,更简单的方法是传入len函数:
#print(people.groupby(len).sum())mapping = {'a': 'red', 'b': 'red', 'c': 'blue',
'd': 'blue', 'e': 'red', 'f' : 'orange'}by_column = people.groupby(mapping, axis=1)
by_column.sum()#Series也有同样的功能,它可以被看做一个固定大小的映射:
map_series = pd.Series(mapping)#还可以利用sample函数
#分类,当分类类别数超过总数,可用replace参数
choices = pd.Series([5, 7, -1, 6, 4])
#print(choices.sample(10,replace=True))
draws = choices.sample(n=10, replace=True)
数据聚合
import pandas as pd
import numpy as nppeople = pd.DataFrame(np.random.randn(5, 5),
columns=['a', 'b', 'c', 'd', 'e'],
index=['Joe', 'Steve', 'Wes', 'Jim', 'Travis'])def peak_to_peak(arr):
return arr.max() - arr.min()#print(people.apply(peak_to_peak))
print(people.agg(peak_to_peak))
数据规整 数据合并连接
针对单独两列数据的合并,目前只想到用concat,merge一直报错
import pandas as pd """
#这两个:一、concat:沿着一条轴,将多个对象堆叠到一起;二、merge:通过键拼接列,是对于dataframe的合并pd.merge(left, right, how='inner', on=None, left_on=None, right_on=None,
left_index=False, right_index=False, sort=True,
suffixes=('_x', '_y'), copy=True, indicator=False,
validate=None)
pd.concat(objs, axis=0, join='outer', join_axes=None, ignore_index=False,
keys=None, levels=None, names=None, verify_integrity=False, copy=True)#https://blog.csdn.net/brucewong0516/article/details/82707492
#https://blog.csdn.net/gdkyxy2013/article/details/80785361
"""#str.cat是针对于拼接而非合并
data = https://www.it610.com/article/{'state':['Ohio1','Ohio1','Ohio2','Nevada3','Nevada3'],
'year':[2000,2001,2002,2001,2002],
'pop':[1.5,1.7,3.6,2.4,2.9],
'salary':['1000K/MTH - 20000K/MTH', '7K/MTH - 8K/MTH',
'10000K/MTH - 16000K/MTH', '3K/MTH - 5K/MTH', '7K/MTH - 12K/MTH',]
}
data = https://www.it610.com/article/pd.DataFrame(data)data['a'] = data['state'].str.cat(data['salary'], sep = '-')
#强制转化成了str之后就可以合并了
data['year_str'] = data['year'].astype('str')
data['b'] = data['state'].str.cat(data['year_str'], sep = '-')
print(data)
#另一组测试数据集
left = pd.DataFrame({'key': ['K0', 'K1', 'K2', 'K3'],
'A': ['A0', 'A1', 'A2', 'A3'],
'B': ['B0', 'B1', 'B2', 'B3']})
right = pd.DataFrame({'key': ['K0', 'K1', 'K2', 'K3'],
'C': ['C0', 'C1', 'C2', 'C3'],
'D': ['D0', 'D1', 'D2', 'D3']})
result = pd.merge(left, right)
print(result)
#针对单独两列数据的合并,目前只想到用concat,merge一直报错
result = pd.concat([left['A'], right['C']], axis = 1)
数据索引分层
import numpy as np
import pandas as pddata = https://www.it610.com/article/pd.Series(np.random.randn(9),
index=[['a', 'a', 'a', 'b', 'b', 'c', 'c', 'd', 'd'],
[1, 2, 3, 1, 3, 1, 2, 2, 3]])
#print(data)
#通过unstack方法将这段数据重新安排到一个完整的DataFrame中:
#print(data.unstack())
#unstack的逆运算是stack:
data.unstack().stack()#可以实现分层索引
frame = pd.DataFrame(np.arange(12).reshape((4, 3)),index=[['a', 'a', 'b', 'b'], [1, 2, 1, 2]],
columns=[['Ohio', 'Ohio', 'Colorado'],
['Green', 'Red', 'Green']])
#各层也可以有名字
frame.index.names = ['key1', 'key2']
frame.columns.names = ['state', 'color']#使用DataFrame的列进行索引########################################
frame = pd.DataFrame({'a': range(7), 'b': range(7, 0, -1),
'c': ['one', 'one', 'one', 'two', 'two',
'two', 'two'],
'd': [0, 1, 2, 0, 1, 2, 3]})#set_index函数会将其一个或多个列转换为行索引,并创建一个新的DataFrame:
frame2 = frame.set_index(['c', 'd'])
print(frame2)
#默认情况下,那些列会从DataFrame中移除,但也可以将其保留下来:
#frame.set_index(['c', 'd'], drop=False)#1.reset_index
#reset_index可以还原索引,重新变为默认的整型索引
frame3 = frame2.reset_index(level = ['c'])
print(frame3)
#内置参数drop可以把原索引列给删除
frame = frame.append(frame).reset_index(drop=True)
#2.reindex,其作用是创建一个新对象,它的数据符合新的索引
obj = pd.Series([4.5, 7.2, -5.3, 3.6], index=['d', 'b', 'a', 'c'])
obj2 = obj.reindex(['a', 'b', 'c', 'd', 'e'])#sort_index:排序
obj=pd.Series([4,9,6,20,4],index=['d','a','e','b','c'])
#按obj的索引排序,默认升序,降序可在括号加ascending=False
print(obj.sort_index())
重命名轴索引
#重命名轴索引##########################
data = https://www.it610.com/article/pd.DataFrame(np.arange(12).reshape((3, 4)),
index=['Ohio', 'Colorado', 'New York'],
columns=['one', 'two', 'three', 'four'])
#1.
transform = lambda x: x[:4].upper()
data.index.map(transform)
#data.rename()#内置参数
数据排序
#排序和排名
obj = pd.Series(range(4), index=['b', 'a', 'b', 'c'])
obj.sort_index()
#索引的is_unique属性可以告诉你它的值是否是唯一的:
#print(obj.index.is_unique)
apply和map和lambda函数
import pandas as pd
'''
apply 用在dataframe上,用于对row或者column进行计算;applymap 用于dataframe上,是元素级别的操作;map (其实是python自带的)用于series上,是元素级别的操作。
'''
df = pd.DataFrame(np.random.randint(0,10,(4, 3)), columns=list('bde'), index=range(4))
f = lambda x: x.max() - x.min()
df.apply(f)
df.apply(f,axis=1)# 作用在一行上
df.apply(f,axis=0)# 作用在一列上,axis=0可省略#applymap: 作用在dataframe的每一个元素上
f2 = lambda x: x+1 if x%2==0 else x
df.applymap(f2)
##############################################
#声明匿名函数
f = lambda x: x.max() - x.min()
#这里的函数f,计算了一个Series的最大值和最小值的差
#在frame的每列都执行了一次。结果是一个Series,使用frame的列作为索引
frame.apply(f)#如果传递axis='columns'到apply,这个函数会在每行执行:
frame.apply(f, axis='columns')#map函数############################
data = https://www.it610.com/article/pd.DataFrame({'food': ['bacon', 'pulled pork', 'bacon',
'Pastrami', 'corned beef', 'Bacon',
'pastrami', 'honey ham', 'nova lox'],
'ounces': [4, 3, 12, 6, 7.5, 8, 3, 5, 6]})
meat_to_animal = {
'bacon': 'pig',
'pulled pork': 'pig',
'pastrami': 'cow',
'corned beef': 'cow',
'honey ham': 'pig',
'nova lox': 'salmon'
}
#Series的map方法可以接受一个函数或含有映射关系的字典型对象
#传入对象
data['animal'] = lowercased.map(meat_to_animal)
#传入函数
data['food'].map(lambda x: meat_to_animal[x.lower()])
时间处理 时间序列基础
【Python|pandas操作指南(超级详细!!!)】ps:'data.a.dt.year’里面的dt是针对series类型的数据,其他的只需要a.year即可
import pandas as pd
import numpy as np
from datetime import datetime
from datetime import timedelta
from dateutil.parser import parse
import pytz
import time#字符串和datetime的互相转换
stamp = datetime(2011, 1, 3)
#print(stamp)
str(stamp)#处理缺失值,配合pandas
idx = pd.to_datetime(datestrs + [None])
pd.isnull(idx)#时间序列基础##############################################
#1.根据标签索引选取数据时,时间序列和其它的pandas.Series很像
dates = [datetime(2011, 1, 2), datetime(2011, 1, 5),
datetime(2011, 1, 7), datetime(2011, 1, 8),
datetime(2011, 1, 10), datetime(2011, 1, 12)]ts = pd.Series(np.random.randn(6), index=dates)
#下面几种用法一样
ts[ts.index[4]]
ts['1/10/2011']
ts['20110110']
ts['2011-1-2']
ts[datetime(2011,1,2)]#对于较长的时间序列,只需传入“年”或“年月”即可轻松选取数据的切片:
#数字个数和日期个数必须对应
longer_ts = pd.Series(np.random.randn(10),
index=pd.date_range('1/1/2000', periods=10))
#用法多样,只要索引符合规范
ts['2011-1-2':]
ts[datetime(2011, 1, 7):]
ts['1/6/2011':'1/11/2011']#2.面这些操作对DataFrame也有效
#生成的就是一个DatetimeIndex
#pd.date_range(start='2012-04-01 12:56:31', periods=20, normalize=True)
# 可以用start或end指定,normalize选项规范化(normalize)到午夜的时间戳
dates = pd.date_range('1/1/2000', periods=100, freq='W-WED')
long_df = pd.DataFrame(np.random.randn(100, 4),
index=dates,
columns=['Colorado', 'Texas',
'New York', 'Ohio'])
long_df.loc['5-2001']#产生重复
dates = pd.DatetimeIndex(['1/1/2000', '1/2/2000', '1/2/2000',
'1/2/2000', '1/3/2000'])
print(dates.dt.tz_convert('America/New_York'))dup_ts = pd.Series(np.arange(5), index=dates)#is_unique可以检查名字是否唯一
dup_ts.index.is_unique#传入level=0:可以把重复的索引分开
grouped = dup_ts.groupby(level = 0)
grouped.mean()
grouped.count()
日期解析和提取
import pandas as pd
import numpy as np
from datetime import datetime
import time ###################解析日期##########################
#datetime.strptime可以用这些格式化编码将字符串转换为日期:
#datetime.strptime是通过已知格式进行日期解析的最佳方式,只能处理单个数据
value = 'https://www.it610.com/article/2011-01-03'
value2 = datetime.strptime(value, '%Y-%m-%d')
datestrs = ['7/6/2011', '8/6/2011']
#中括号得加
value3 = [datetime.strptime(x, '%m/%d/%Y') for x in datestrs]
#print(value3)#dateutil可以解析几乎所有人类能够理解的日期表示形式:
(parse('2011-01-03'))
(parse('Jan 31, 1997 10:45 PM'))
#在国际通用的格式中,日出现在月的前面很普遍,传入dayfirst=True
parse('6/12/2011', dayfirst=True)#处理成组的日期
datestrs = ['2011-07-06 12:00:00', '2011-08-06 00:00:00']
pd.to_datetime(datestrs)
#带有中文的日期格式
#1.单个操作,如要多组数据,用for语句
value = 'https://www.it610.com/article/2011年1月3号'
value2 = datetime.strptime(value, '%Y年%m月%d号')#2.多组操作,适用于dataframe类型
datestrs = ['2011-07-06 12:00:00', '2011-08-06 00:00:00']
datestr = pd.to_datetime(datestrs)
#针对有特定类型的日期类型
x = ['2011年7月6号', '2011年7月9号']
y = pd.to_datetime(x, format = '%Y年%m月%d号')#################转换和提取#################
data = https://www.it610.com/article/{'state':['Ohio2','Ohio2','Ohio2','Nevada2','Nevada2'],
'year':['2002/1/2','2012/3/4','2022/5/6','2012/7/8','2022/9/10'],
'pop':[1.52,1.72,3.62,2.42,2.92],
'salary':['5000K/MTH - 20000K/MTH', '12K/MTH - 19K/MTH',
'4000K/MTH - 6000K/MTH', '14000K/MTH - 22000K/MTH','8000K/MTH - 20000K/MTH'],
'create_time':[1462451334, 1462451335, 1461231336, 1462451337, 1462451338]
}
data = https://www.it610.com/article/pd.DataFrame(data)
data['a'] = pd.to_datetime(data.year, format = '%Y-%m-%d')
#print(data)
#提取出年月日
#print(data.a.dt.year, data.a.dt.month, data.a.dt.day)#python中type,dtype,astype的作用与使用要注意,第一个针对单个,第二个针对数组等多个元素
print(type(data.a.dt.year))
print(data.a.dt.year.dtype)#时间戳转换
timestamp = 1462451334#转换成localtime
time_local = time.localtime(timestamp)
#转换成新的时间格式(2016-05-05 20:28:54)
dt = time.strftime("%Y-%m-%d %H:%M:%S",time_local)
print (dt)#pandas里面时间戳转换
data['date']= pd.to_datetime(data['create_time'].values, utc=True, unit='s').tz_convert(
"Asia/Shanghai").to_period("D")
print(data)
时区转换
#时区划分
#时区名字
#时区是以UTC偏移量的形式表示的
pytz.common_timezones[1:15]
#获取时区对象
tz = pytz.timezone('America/New_York')#freq就表示时间频率,D代表day,W就代表week,tz就代表时区
rng = pd.date_range('3/9/2012 9:30', periods=6, freq='D')
#rng2已经规定了时区,相当于已经本地化过了
rng2 = pd.date_range('3/9/2012 9:30', periods=6, freq='D', tz='UTC')#print(rng.tz_localize('Asia/Shanghai'))
#从单纯到本地化的转换是通过tz_localize方法处理的:
ts_utc = rng.tz_localize('UTC')
#print(ts_utc)
#一旦时间序列被本地化到某个特定时区,就可以用tz_convert将其转换到别的时区了:
#print(ts_utc.tz_convert('America/New_York'))#tz_localize和tz_convert也是DatetimeIndex的实例方法:
ts = pd.Series(np.random.randn(len(rng)), index=rng)
#print(ts.index)
#print(ts.index.tz_localize('Asia/Shanghai'))#srtftime的使用
正则表达式
#pandas里面的正则###############################################
#1.extract使用
#如果提取的规则结果有多组,则会返回数据框,不匹配的返回NaN
s3 = pd.Series(['a1', 'b2', 'c3'])
print(s3.str.extract('([ab])(\d)'))
#print(pd.Series(s3).str.extract('([ab])(\d)', expand=False))
print(pd.Series(['a1', 'b2', 'c3']).str.extract('([ab])(\d)', expand=False))#2.contains使用正则表达式,
#可以将符合的数据进行提取
#print(s3.str.contains('([ab])(\d)'))
#print(s3[s3.str.contains('([ab])(\d)')].unique())data = https://www.it610.com/article/{'state':['Ohio1','Ohio1','Ohio2','Nevada3','Nevada3'],
'year':[2000,2001,2002,2001,2002],
'pop':['1.5','1.7','3.6','2.4','2.9'],
'salary':['1000K/MTH - 20000K/MTH', '7K/MTH - 8K/MTH',
'10000K/MTH - 16000K/MTH', '3K/MTH - 5K/MTH', '7K/MTH - 12K/MTH',]
}
frame = pd.DataFrame(data)#series是将数据形成一个个的列表
#正则记得加括号
#print(pd.Series(data['pop']).str.extract('(\d+\.?\d)'))#series和dataframe#####################################################################
#注意:extract在dataframe中也适用,不需要再次series,其实series相当于dataframe的一列而已
#所以,诸如head,unique,describe对于dataframe可用的对于series也可用
#print(frame['pop'].str.extract('(\d+\.?\d)'))
#这两个结果就是一样的
#print(pd.Series(data['pop']),'\n', frame['pop'])#打换行符的时候,需要用引号弄起来哦
data2 = ['1.5','1.7','3.6','2.4','2.9']
#纯数字列表无法用.str方法
#data2 = [1.5,1.7,3.6,2.4,2.9]#print(data2, '\n' , pd.Series(data2))
data3 = pd.Series(data2)
#print(data3.str.extract('(\d+\.?\d)'))#re在字符串和pandas中的应用######################################################
#若是字典,那么键值将充当索引
data = https://www.it610.com/article/{'Dave': 'dave@google.com', 'Steve': 'steve@gmail.com',
'Rob': 'rob@gmail.com', 'Wes': np.nan}data = https://www.it610.com/article/pd.Series(data)
#提取,但是.str只针对dataframe或series形式
#print(data.str[:5])data.isnull()
data.str.contains('gmail')
pattern = '([A-Z0-9._%+-]+)@([A-Z0-9.-]+)\\.([a-z]{2,4})'#这里用加号和括号就可以把正则提取的东西分别存储在列表中
#print(data.str.extract('([a-z0-9._%+-]+)(@+)([a-z0-9.-]+)\\.([a-z]{2,4})'))#使用正则表达式,还可以加上任意re选项(如IGNORECASE),这个貌似不看大小写吧好像
#print(data.str.findall(pattern, flags=re.IGNORECASE))#获取true或false
matches = data.str.match(pattern, flags=re.IGNORECASE)#例子########################################################
def Find(string):
# findall() 查找匹配正则表达式的字符串
url = re.findall('https?://(?:[-\w.]|(?:%[\da-fA-F]{2}))+', string)
#'https://([\w.])+'也是对的
return url
string = 'Runoob 的网页地址为:https://www.runoob.com,Google 的网页地址为:https://www.google.com'
print("Urls: ", Find(string))
'''
另外一些函数(sum,count,add,fill)
import pandas as pddata = https://www.it610.com/article/{'state':['Ohio2','Ohio2','Ohio2','Nevada2','Nevada2'],
'year':[2002,2012,2022,2012,2022],
'pop':[1.52,1.72,3.62,2.42,2.92],
'salary':['5000K/MTH - 20000K/MTH', '12K/MTH - 19K/MTH',
'4000K/MTH - 6000K/MTH', '14000K/MTH - 22000K/MTH','8000K/MTH - 20000K/MTH']
}
frame = pd.DataFrame(data)
#这个只针对非str的数据相加求总和
print(frame.groupby(data['state']).sum())
#这个则是分组计算数目
print(frame.groupby(data['state']).count())#使用df1的add方法,传入df2以及一个fill_value参数,就是一个填充值,不然会用NaN代替,他的数学运算是按照索引一一对应!
#print(s1.add(s2,fill_value = https://www.it610.com/article/0))
#实例
#当计算结果为NAN时,需要用特定的值来补充代替
import pandas as pd
s1=pd.Series([1,2,3,4],index=['a','b','c','d'])
s2=pd.Series([10,20,30,40],index=['c','d','e','f'])
s3=pd.Series([1,2,3,4],index=['a','b','c','d'])
s4=pd.Series([10,20,30,40],index=['c','d','e','f'])
print (s1+s2) #--1--直接相加只有索引c\d对应有值
print ((s1+s2).dropna())#--2--去除值为空的
print ((s1+s2).fillna(0))#--3--把值为空的地方填充成0
print (s1.add(s2,fill_value=https://www.it610.com/article/1)) #--4--s1和s2相加,当索引对应值不存在,用1代替s2中元素和s1相加#针对索引
#pandas可以对不同索引的对象进行算术运算。在将对象相加时,如果存在不同的索引对,则结果的索引就是该索引对的并集。
s1 = pd.Series([7.3, -2.5,'', 1.5], index=['a', 'c', 'd', 'e'])
s2 = pd.Series([-2.1, 3.6, -1.5, 4],index=['a', 'c', 'e', 'f'])
print(s1 + s2)
典型筛选案例 自定义函数
import pandas as pd
import numpy as np
import re#针对于字符串的替换筛选###########################################
salary = ['8千-1万', '5千-8千', '面议', '1.5万-2万', '1.5万-3万', '1万-1.5万', '7千-1.5万',
'1.5万-2.5万', '1万-2万', '8千-1.5万', '2.5万以上', '7千-1万', '3千-8千',
'2千-1万', '5千-1万', '4千-1万', '5千-6千', '3千-5千', '2万-2.5万', '6千-1万']
salary = pd.Series(salary)def process_k(data):
if '千' in data:
return float(data.replace('千', '')) * 1000
elif '万' in data:
return float(data.replace('万', '')) * 10000def process_salary(data):
if data =https://www.it610.com/article/='面议':
return np.nan
if '万以上' in data:
return float(data.replace('万以上', '')) * 10000
if '千以下' in data:
return float(data.replace('千以下', '')) * 1000
if '-' in data:
low, high = data.split('-')
return (process_k(low) + process_k(high))/2salary_clean = salary.apply(process_salary)
#salary_clean = salary_clean[salary_clean>10000]
print(salary_clean)
#print(salary_clean.unique())#针对于数字和字符串的清洗筛选############################################
data = https://www.it610.com/article/{'state':['Ohio1','Ohio1','Ohio2','Nevada3','Nevada3'],
'year':[2000,2001,2002,2001,2002],
'pop':[1.5,1.7,3.6,2.4,2.9],
'salary':['1000K/MTH - 20000K/MTH', '7K/MTH - 8K/MTH',
'10000K/MTH - 16000K/MTH', '3K/MTH - 5K/MTH', '7K/MTH - 12K/MTH']
}
frame = pd.DataFrame(data)def get_salary_jlc(data):
pat_jlc = r"(.*)K/MTH - (.*)K/MTH"
if '00' in data:
low, high = re.findall(pattern=pat_jlc, string=data)[0]
return (float(low)+float(high))/2/1000
else:
low, high = re.findall(pattern=pat_jlc, string=data)[0]
return (float(low)+float(high))/2frame['salary_clean'] = frame['salary'].apply(get_salary_jlc)#print(frame.head())
#print(frame['salary'].iloc[:3])
x = re.findall("(.*)K/MTH - (.*)K/MTH", '1000K/MTH - 20000K/MTH')
#print(x)
low, high = re.findall("(.*)K/MTH - (.*)K/MTH", '1000K/MTH - 20000K/MTH')[0]
#print(low,' ', high)
函数组合
#所有元素的累计和
print(data['a'].astype('int64').sum())
print(data['a'].cumsum())
print(data['a'].astype('int64').sort_values(ascending = False))
'''
#非空元素的数量
print(data['b'].notnull().sum())
#第a列索引为2的元素
print(data.a[2])#检测和过滤异常值,一般就依靠算法了#####################
#生成4组,每一组包含1000个元素,numpy.random.rand()则相反
data = https://www.it610.com/article/pd.DataFrame(np.random.randn(1000, 4))
#print(data[2][np.abs(data[2])>3])
#print(data[(np.abs(data) > 3).any(1)])#字符串对象方法###########################
val = 'a,b,guido'
val1 = val.split(',')
#strip方法不支持列表操作
pieces = [x.strip() for x in val.split(',')]
print(val1,' ',pieces)
#可以直接赋值
first, second, third = pieces
#下面两种方法一样
first + '::' + second + '::' + third
'::'.join(pieces)
其他(重采样,take,data-dict转换等)
import numpy as np;
import pandas as pdvalues = pd.Series([0, 1, 0, 2] * 2)
dim = pd.Series(['apple', 'orange','banana'])#可以使用take方法存储原始的字符串Series:
#用于分类,但是values和dim里面的类别数量必须相等,否则报错
#print(dim.take(values))#
fruits = ['apple', 'orange', 'apple', 'apple'] * 2N = len(fruits)
df = pd.DataFrame({'fruit': fruits,
'basket_id': np.arange(N),
'count': np.random.randint(3, 15, size=N),
'weight': np.random.uniform(0, 4, size=N)},
columns=['basket_id', 'fruit', 'count', 'weight'])#dtypes(查询数据类型) 、astype(强制转换数据类型)
fruit_cat = df['fruit'].astype('category')
#print(fruit_cat)#GroupBy高级应用#################################
df = pd.DataFrame({'key': ['a', 'b', 'c'] * 4,
'value': np.arange(12.)})g = df.groupby(df['key'])
print(g.mean())#重采样
df = pd.DataFrame({'time': np.arange(N * 3.),
'key': np.tile(['a', 'b', 'c'], N),
'value': np.arange(N * 3.)})
print(df)
print(df.set_index('key'))#下面用法自行体会
data = https://www.it610.com/article/{'col_1': [3, 2, 1, 0], 'col_2': ['a', 'b', 'c', 'd']}
data1 = pd.DataFrame.from_dict(data)
data2 = pd.DataFrame(data)
data3 = pd.DataFrame.from_dict(data, orient='index',
columns=['A', 'B', 'C', 'D'])
print(data1)
print(data2)
print(data3)
numpy基础
import numpy as npmy_arr = np.arange(10)
#print((my_arr)[1])
my_list = list(range(10))
#print(my_list[1])arr = np.arange(8)
#1.数组重塑###################################################
arr2 = arr.reshape(4,2)
#reshape将一维数组转换为多维数组的运算过程相反的运算通常称为扁平化(flattening)或散开(raveling):
arr3 = arr2.ravel()
arr4 = arr2.flatten()
#print(arr3, arr4)#2.数据的合并和拆分#############################################3
arr1 = np.array([[1, 2, 3], [4, 5, 6]])
arr2 = np.array([[7, 8, 9], [10, 11, 12]])
#按列合并
np.concatenate([arr1, arr2], axis=0)
#按行合并
np.concatenate([arr1, arr2], axis=1)#对于常见的连接操作,NumPy提供了一些比较方便的方法(如vstack和hstack)
#按列合并
np.vstack((arr1, arr2))
#按行合并
np.hstack((arr1, arr2))#与此相反,split用于将一个数组沿指定轴拆分为多个数组:传入到np.split的值[1,3]指示在哪个索引处分割数组。
arr = np.random.randn(5, 2)
first, second, third = np.split(arr, [1,3])#3.元素的重复操作:tile和repeat######################################
arr = np.arange(3)
arr.repeat(3)
#如果传入的是一组整数,则各元素就可以重复不同的次数:但是个数也必须对应
#同样,在对多维进行重复时,也可以传入一组整数,这样就会使各切片重复不同的次数:
arr.repeat([2, 3, 4])
#对于多维数组,还可以让它们的元素沿指定轴重复:
arr = np.random.randn(2, 2)
arr.repeat(2, axis = 1)
#注意,如果没有设置轴向,则数组会被扁平化,这可能不会是你想要的结果
#print(arr.repeat(2))#4.索引:################################################
# 获取和设置数组子集的一个办法是通过整数数组使用花式索引:
arr = np.arange(10) * 100
inds = [7, 1, 2, 6]
#两种方法一样
arr[inds]
arr.take(inds)
#在inds索引处的数用42代替
arr.put(inds, 42)#要在其它轴上使用take,只需传入axis关键字即可:
arr = np.random.randn(2, 4)
print(arr)
#抽取arr按行的每个数据的第1,2个
print(arr.take([0, 1], axis =1))
我写不动了,下次再补。。。
推荐阅读
- sklearn实战|sklearn实战之数据预处理与特征工程
- python机器学习与数据挖掘|数据预处理(七)——利用sklearn进行数据预处理
- 数据分析|Python 疫情数据的可视化与分析(二)
- 抖音解析|短视频搬运软件(抖音批量解析下载一个作者所有视频)
- 大数据可视化|Python疫情数据可视化分析+数据预测(pandas+pyecharts+statsmodels+matplotlib+sql)
- HaaS解决方案|看屏幕眼睛干(没问题 用ESP32和 HaaS Python做一个 全自动加湿器)
- HaaS解决方案|开工大吉,ESP32 + HaaS Python为您送上久坐提醒器,好好工作更要注意健康哦
- HaaS解决方案|用ESP32打造一个物联网红外测温打卡机/春节结束急着上班(哒咩,再努力奋斗也要先测体温)
- HaaS解决方案|绿色节能,怎么用ESP32 + HaaS Python怎么做一个起夜小灯(接上个“智慧路灯”案例中的留下的地下室人体感应亮灭灯)