导读:Pandas.此文稍长,但是包括了pandas的基础入门使用以及一些进阶部分:时间序列,数据清洗预处理等操作,当然要学习了解更多细节和操作去翻阅Pandas官方的操作手册也是必不可少的。.基础部分.导入pandas import pandas as pd.查看版本信息 pd.__
此文稍长,但是包括了pandas的基础入门使用以及一些进阶部分:时间序列,数据清洗预处理等操作,当然要学习了解更多细节和操作去翻阅Pandas官方的操作手册也是必不可少的。
import pandas as pd
pd.__version__
从列表中创建Series: S = pd.Series(data=['1','2','3','4'],index=['a','b','c','d'],name='CreatedSeries')
从字典中创建:
d = {'a': 1, 'b': 2, 'c': 3, 'd': 4, 'e': 5}
s2 = pd.Series(d)
从Ndarrray创建
import numpy as np
n = np.random.randn(5) s3 = pd.Series(data=n)
S.index=[...]
,Series.reindex([...])
pd.concat([s1,s2])
S.drop('a')
S['d']=1
或S.loc['d']=1
S.['d']
或S.loc['d']
S[:]
参考列表切片操作 按照索引进行计算,所以不同则为NaN
空值,下面以S与自身运算为例
四则运算如下:
S.add(S)
S.sub(S) S.mul(S) S.div(S)
求中位数、求和、最值:
res6 = S.median() # 中位数
res7 = S.sum() # 求和 res8 = S.max() # 最大值 res9 = S.min() # 最小值
从Numpy数组创建:
dates = pd.date_range('today', periods=6) # 定义时间序列作为 index
num_arr = np.random.randn(6, 4) # 传入 numpy 随机数组 column_name = [‘A’, ‘B’, ‘C’, ’D’] df1 = pd.DataFrame(data=num_arr,index=dates,columns=column_name)
通过数组字典创建:
data = {'animal': ['cat', 'cat', 'snake', 'dog', 'dog', 'cat', 'snake', 'cat', 'dog', 'dog'],
'age': [2.5, 3, 0.5, np.nan, 5, 2, 4.5, np.nan, 7, 3],
'visits': [1, 3, 2, 3, 2, 3, 1, 1, 2, 1],
'priority': ['yes', 'yes', 'no', 'yes', 'no', 'no', 'no', 'yes', 'no', 'no']}
labels = [‘a’, ‘b’, ‘c’, ’d’, ‘e’, ‘f’, ‘g’, ‘h’, ‘i’, ‘j’] df2 = pd.DataFrame(data,index=labels)
查看DataFrame数据类型: df2.dtypes
了解陌生数据集结构(尤其是数据量大的数据)
# 查看前5行
df2.head() # 可以通过传递整数参数来指定显示行数
df2.tail(3) # 默认显示后5行
查看索引:df1.index
查看列名:df2.columns
查看数值:df2.values
查看统计数据:df2.describe(include='all') # 默认只统计数值列数据,查看所有列就需要参数 include='all'
转置操作:df1.T
按列排序:df1.sort_values(by='A',ascending=False) #以A列的值降序排列
切片操作:df1[:6:2]
通过标签查询单列和多列
df1['A'] # 查询A列
df1.A # 查询A列等价写法 df1[[‘A’,‘B’]] # 查询A列和B列
多条件查询
df1[(df1['A']>0) & (df1['B']<0)]
按位置查询
.loc[]
方法用于根据标签名称索引,行和列对应的名称
.iloc[]
方法用于根据整数位置索引,行和列都是从0开始编号
row = df1.iloc[1] # 按行位置查询
col = df1.iloc[:,2] # 按列位置查询 arr = df1.iloc[:5,:3] # 前五行前三列
副本拷贝:df3= df2.copy # 从df2生成DataFrame副本df3
判断元素是否为空:
df2.isnull() # 判断整个df2元素是否为空值
df2[‘age’].isnull() # 判断df2中的age列元素是否为空值
添加列数据:
num = pd.Series([0,1,2,3,4,5,6,7,8,9],index=df3.index) # 需要插入的列
df3[‘No.’]=num # num插入到df3中命名为’No.‘
数据修改:
df2.iloc[2,1]=1 # 修改了第三行第二列的数据df2.iat[2,1]=1 # 等价与前一种
df2.loc['a','age']=3 # 修改了名为'a’行,‘age'列的数据
求和、求平均值操作等
df2.median()
df2[‘age’].sum()
字符串操作
大小写转换:
string = pd.Series(['A', 'B', 'C', 'Aaba', 'Baca',np.nan, 'CABA', 'dog', 'cat'])
print(string) string.str.lower() # 字符串转换为小写 string.str.upper() # 将字符串换为大写
分割字符串:
import pandas as pd
data = pd.Series([‘apple,banana,cherry’, ‘date,fig’]) print(data)
split_data = data.str.split(‘,’) print(split_data)
缺失值操作:
检测缺失值:isna()
和notna()
:这两个方法用于检测缺失值。isna()
返回一个布尔值Series,指示每个元素是否为缺失值。notna()
返回一个布尔值Series,指示每个元素是否不是缺失值
data = pd.Series([1, 2, np.nan, None])
print(data.isna()) print(data.notna())
删除缺失值:dropna()
:该方法用于删除包含缺失值的行或列。默认情况下,它会删除包含任何缺失值的行。可以使用axis
参数指定删除的轴,axis=0
表示删除行,axis=1
表示删除列
data = pd.DataFrame({'A': [1, 2, np.nan],
'B': [4, np.nan, 6],
'C': [np.nan, 8, 9]})
print(data) cleaned_data = data.dropna() print(cleaned_data) cleaned_data_col = data.dropna(axis=1) print(cleaned_data_col)
指定列对齐:
# 创建两个示例DataFrame
df1 = pd.DataFrame({‘A’: [1, 2, 3], ‘B’: [4, 5, 6]}) df2 = pd.DataFrame({‘C’: [7, 8, 9], ’D’: [10, 11, 12]})
df1_aligned, df2_aligned = df1.align(df2, join=‘inner’, axis=0, level=None, copy=False)
print(df1_aligned) print(df2_aligned)
列名的重命名:
import pandas as pd
df = pd.DataFrame({‘A’: [1, 2, 3], ‘B’: [4, 5, 6]})
new_column_names = [‘X’, ‘Y’]
df = df.rename(columns=dict(zip(df.columns, new_column_names))) print(df)
pd.read_csv()
、pd.read_excel()
等方法对不同文件读取df.to_excel()
、df.to_json()
等方法进行写入,此处的df是一个DataFrame对象建立一个以 2018 年每一天为索引,值为随机数的 Series:
import pandas as pd import numpy as np
dti = pd.date_range(start=‘2018-01-01’, end=‘2018-12-31’, freq=’D’) s = pd.Series(np.random.rand(len(dti)), index=dti)
统计每一个周三对应值的和:
# 周一从 0 开始
s[s.index.weekday == 2].sum()
统计每个月的平均值:
s.resample('M').mean()
pandas中的resample()
函数对时间序列数据进行重采样
时间转换:
s = pd.date_range('today', periods=100, freq='S')
ts = pd.Series(np.random.randint(0, 500, len(s)), index=s)
sum1 = ts.resample(‘Min’).sum() sum2 = ts.resample(‘H’).sum() “’ 注意使用sum()重采样聚合后 sum1与sum2值相等 “’
时间标准转换:
s = pd.date_range('today', periods=1, freq='D') # 获取当前时间
ts = pd.Series(np.random.randn(len(s)), s) # 随机数值 ts_utc = ts.tz_localize(‘UTC’) # 转换为 UTC 时间 ts_utc.tz_convert(‘Asia/Shanghai’) # 转换为上海时间
不同时间表示方式转换:
rng = pd.date_range('1/1/2018', periods=5, freq='M')
ts = pd.Series(np.random.randn(len(rng)), index=rng) print(ts) ps = ts.to_period() print(ps) ps.to_timestamp()
创建多重索引:
letters = ['A', 'B', 'C']
numbers = list(range(10))
mi = pd.MultiIndex.from_product([letters, numbers]) # 设置多重索引 s = pd.Series(np.random.rand(30), index=mi) # 随机数
根据多重索引查询:
# 查询索引为 1,3,6 的值
s.loc[:, [1, 3, 6]]
多重索引切片:
s.loc[pd.IndexSlice[:'B', 5:]]
创建带有多重索引的DataFrame:
frame = pd.DataFrame(np.arange(12).reshape(6, 2),
index=[list('AAABBB'), list('123123')],
columns=['hello', 'shiyanlou'])
多重索引设置列名称:
frame.index.names = ['first', 'second']
多重索引分组求和:
frame.groupby('firsr').sum
行列名称转换:
print(frame)
frame.stack()
索引转换:
frame.unstack()
条件查找 :
# 示例数据
data = {‘animal’: [‘cat’, ‘cat’, ‘snake’, ‘dog’, ‘dog’, ‘cat’, ‘snake’, ‘cat’, ‘dog’, ‘dog’], ‘age’: [2.5, 3, 0.5, np.nan, 5, 2, 4.5, np.nan, 7, 3], ‘visits’: [1, 3, 2, 3, 2, 3, 1, 1, 2, 1], ‘priority’: [‘yes’, ‘yes’, ‘no’, ‘yes’, ‘no’, ‘no’, ‘no’, ‘yes’, ‘no’, ‘no’]}
labels = [‘a’, ‘b’, ‘c’, ’d’, ‘e’, ‘f’, ‘g’, ‘h’, ‘i’, ‘j’] df = pd.DataFrame(data, index=labels)
df[df[‘age’]>3]
df[(df[‘animal’] == ‘cat’) & (df[‘age’] < 3)]
按关键字查询:
df[df['animal'].isin(['cat','dog'])]
按标签及列名查询:
df.loc[df.index[[3,4,8]],['animal','age']]
多条件排序 :
# 字段`age`降序,`visits`升序来进行排序
df.sort_values(by=['age','visits'], ascending=[False,True])
多值替换 :对某一列数据使用map
函数进行替换
df['priority'].map({'yes':True, 'no':False})
分组求和 :
df.groupby('animal').sum()
df.groupby([‘animal’,‘age’]).sum()
拼接 多个DataFrame
temp_df1 = pd.DataFrame(np.random.randn(5, 4)) # 生成由随机数组成的 DataFrame 1
temp_df2 = pd.DataFrame(np.random.randn(5, 4)) # 生成由随机数组成的 DataFrame 2 temp_df3 = pd.DataFrame(np.random.randn(5, 4)) # 生成由随机数组成的 DataFrame 3
print(temp_df1) print(temp_df2) print(temp_df3)
pieces = [temp_df1, temp_df2, temp_df3] pd.concat(pieces)
找出和最小的列:
df = pd.DataFrame(np.random.random(size=(5, 10)), columns=list('abcdefghij'))
df.sum().idxmin()
每个元素减去每一行的平均值:
df = pd.DataFrame(np.random.random(size=(5, 3)))
df.sub(df.mean(axis=1), axis=0)
DataFrame分组,并得到每一组中最大三个数之和:
df = pd.DataFrame({'A': list('aaabbcaabcccbbc'),
'B': [12, 345, 3, 1, 45, 14, 4, 52, 54, 23, 235, 21, 57, 3, 87]})
print(df) df.groupby(‘A’)[‘B’].nlargest(3).sum(level=0)
DataFrame 分组 ,并得到每一组中最大三个数之和 :
df = pd.DataFrame({'A': list('aaabbcaabcccbbc'),
'B': [12, 345, 3, 1, 45, 14, 4, 52, 54, 23, 235, 21, 57, 3, 87]})
df.groupby(‘A’)[‘B’].nlargest(3).sum(level=0) df.nlargest(3,‘B’) # 获取df中B列值最大的前三行
当分析庞大的数据时,为了更好的发掘数据特征之间的关系 ,且不破坏原数据,就可以利用透视表 pivot_table
进行操作
透视表的创建:
df = pd.DataFrame({'A': ['one', 'one', 'two', 'three'] * 3,
'B': ['A', 'B', 'C'] * 4,
'C': ['foo', 'foo', 'foo', 'bar', 'bar', 'bar'] * 2,
'D': np.random.randn(12),
'E': np.random.randn(12)})
pd.pivot_table(df, index=[‘A’, ‘B’, ‘C’])
按照指定列进行聚合:
# 将以D列聚合,按照A,B列为索引进行聚合,聚合的方式为默认求平均值
pd.pivot_table(df, values=[’D’], index=[‘A’, ‘B’])
透视表聚合方式定义:
# 当 aggfunc 是一个函数列表时,将同时应用多个聚合函数,并返回一个具有多级列索引的数据框
pd.pivot_table(df, values=[’D’], index=[‘A’, ‘B’], aggfunc=[np.sum, len])
透视表利用额外列进行辅助分割:
#`D` 列按照 `A,B` 列进行聚合时,若关心 `C` 列对 `D` 列的影响,可以加入 `columns` 值进行分析
pd.pivot_table(df, values=[’D’], index=[‘A’, ‘B’], columns=[‘C’], aggfunc=np.sum)
透视表中对缺省值处理:
# 在透视表中由于不同的聚合方式,相应缺少的组合将为缺省值,可以加入 `fill_value` 对缺省值处理
pd.pivot_table(df, values=[’D’], index=[‘A’, ‘B’], columns=[‘C’], aggfunc=np.sum, fill_value=0)
在数据的形式上主要包括数量型和性质型,数量型表示着数据可数范围可变,而性质型表示范围已经确定不可改变,绝对型数据就是性质型数据的一种
绝对型数据定义:
df = pd.DataFrame({"id": [1, 2, 3, 4, 5, 6], "raw_grade": [
'a', 'b', 'b', 'a', 'a', 'e']})
df[“grade”] = df[“raw_grade”].astype(“category”
对绝对型数据重命名:
df["grade"].cat.categories = ["very good", "good", "very bad"]
绝对型数据其他操作:
# 排序
df.sort_values(by=“grade”)
df.groupby(“grade”).size()
经常得到的数据不符合最终处理的数据要求,包括了缺省值以及坏的数据,需要我们对数据进行清洗
缺失值拟合
df = pd.DataFrame({'From_To': ['LoNDon_paris', 'MAdrid_miLAN', 'londON_StockhOlm',
'Budapest_PaRis', 'Brussels_londOn'],
'FlightNumber': [10045, np.nan, 10065, np.nan, 10085],
'RecentDelays': [[23, 47], [], [24, 43, 87], [13], [67, 32]],
'Airline': ['KLM(!)', '<Air France> (12)', '(British Airways. )',
'12. Air France', '"Swiss Air"']})
df[‘FlightNumber’] = df[‘FlightNumber’].interpolate().astype(int)
数据列拆分
# 将上一步生成的df中的From_To列通过split进行拆分为独立两列为新表
temp = df.FromTo.str.split(’’, expand=True) temp.columns = [‘From’, ‘To’]
字符标准化
# 对地名姓名进行标准化处理
temp[‘From’] = temp[‘From’].str.capitalize() temp[‘To’] = temp[‘To’].str.capitalize()
删除坏数据加入整理好的数据
# 将原来的From_to列删除,加入整理好的From和to列
df = df.drop(‘From_To’, axis=1) df = df.join(temp) print(df)
去除多余字符
df['Airline'] = df['Airline'].str.extract(
'([a-zA-Z\s]+)', expand=False).str.strip()
格式规范:
上面df中的RencentDelays
中记录的方式为列表类型,但是列表的长度不一,后期处理分析会比较麻烦,此时将其拆开,去除列表中相同位置元素作为一列,若为空值用NaN
代替
delays = df['RecentDelays'].apply(pd.Series)
delays.columns = [‘delay_{}’.format(n) for n in range(1, len(delays.columns)+1)]
df = df.drop(‘RecentDelays’, axis=1).join(delays)
信息区间划分:
# 将grades按照是否大于60来划分
df = pd.DataFrame({‘name’: [‘Alice’, ‘Bob’, ‘Candy’, ‘Dany’, ‘Ella’, ‘Frank’, ‘Grace’, ‘Jenny’], ‘grades’: [58, 83, 79, 65, 93, 45, 61, 88]})
def choice(x): if x > 60: return 1 else: return 0
df.grades = pd.Series(map(lambda x: choice(x), df.grades))
数据区重复:
df = pd.DataFrame({'A': [1, 2, 2, 3, 4, 5, 5, 5, 6, 7, 7]})
df.loc[df[‘A’].shift() != df[‘A’]]
上一篇:软件开发项目文档系列之三如何撰写
下一篇:代码大全-如何建立一个高质量的子