| 数据类型 | 说明 | Pandas读取方法 |
|---|---|---|
| csv、tsv、txt | 逗号分隔、tab分割的纯文本文件 | pd.read_csv |
| excel | 微软xls或者xlsx文件 | pd.read_excel |
| mysql | 关系型数据库 | pd.read_sql |
csv,使用默认的标题行、逗号分隔符import pandas as pd
# 读取文件
fpath = './data/ratings.csv'
ratings = pd.read_csv(fpath)
fpath:文件路径sep:数据分隔符header:names:某些数据没有表头,可以自定义列名,数组类型ratings.head()
ratings.shape
ratings.columns
ratings.index
ratings.dtypes
import pandas as pd
fpath = './data/access_pvuv.xlsx'
ratings = pd.read_excel(fpath)


import pymysql
import pandas as pd
conn = pymysql.connect(
host="127.0.0.1",
user="admin",
password="password",
database="test",
charset="utf8"
)
mysql_page = pd.read_sql("select * from crazyant_pvuv", conn=conn)

DataFrame是一个表格型的数据结构index,也有列索引columnsSeries组成的字典DataFrame常用方法1.读取纯文本文件
2.读取excel文件
3.读取mysql数据库
4.从数据源创建
import pandas as pd
data = {
"state": ['Ohio', 'Ohio', 'Ohio', 'Nevada', 'Nevada'],
"year": [2000, 2001, 2002, 2001, 2002],
"pop": [1.5, 1.7, 3.6, 2.4, 2.9]
}
df = pd.DataFrame(data)
state year pop
0 Ohio 2000 1.5
1 Ohio 2001 1.7
2 Ohio 2002 3.6
3 Nevada 2001 2.4
4 Nevada 2002 2.9
Series是一种类似于一维数组的对象,类似于python的字典,它由一组数据(可以是不同数据类型)以及一组与之相关的数据标签(即索引)组成Series常用方法1.使用列表数据生成一个最简单的Series
import pandas as pd
s1 = pd.Series([1, 'a', 5, True, [1]])
0 1
1 a
2 5
3 True
4 [1]
dtype: object
s1.index # RangeIndex(start=0, stop=5, step=1)
s1.values # array([1, 'a', 5, True, list([1])], dtype=object)
2.创建一个具有标签索引的Series
import pandas as pd
s2 = pd.Series([1, 'a', 5, True, [1]], index=['a', 'b', 'c', 'd', 'e'])
a 1
b a
c 5
d True
e [1]
dtype: object
s2['a'] # 1
type(s2['a']) # int
s2[['a', 'b']]
'''
a 1
b a
dtype: object
'''
type(s2[['a', 'b']]) # pandas.core.series.Series
2.使用Python字典创建Series
import pandas as pd
sdata = {'Ohio': 35000, 'Texas': 72000, 'Oregon': 16000, 'Utah': 5000}
s3 = pd.Series(sdata)
Ohio 35000
Texas 72000
Oregon 16000
Utah 5000
dtype: int64
DataFrame中查询出Seriespd.Seriespd.DataFramestate索引列数据import pandas as pd
data = {
"state": ['Ohio', 'Ohio', 'Ohio', 'Nevada', 'Nevada'],
"year": [2000, 2001, 2002, 2001, 2002],
"pop": [1.5, 1.7, 3.6, 2.4, 2.9]
}
df = pd.DataFrame(data)
type(df['state']) # pandas.core.series.Series
# 查询第一行
# type(df.loc[0]) # pandas.core.series.Series
state、year索引列数据import pandas as pd
df[['state', 'year']]
'''
state year
0 Ohio 2000
1 Ohio 2001
2 Ohio 2002
3 Nevada 2001
4 Nevada 2002
'''
type(df[['state', 'year']]) # pandas.core.frame.DataFrame
# 查询前两行
# type(df.loc[0: 1]) # pandas.core.frame.DataFrame
# df.loc[0: 1] # 包含尾部索引
'''
state year pop
0 Ohio 2000 1.5
1 Ohio 2001 1.7
'''
df.loc1.数据读取
df.read_csv('./data/beijing_tianqi_2018.csv')
2.设置索引为日期,方便按日期筛选
df.set_index('year', drop=True, append=False, inplace=False, verify_integrity=False)
drop:是否删除作为索引使用的列,默认删除append:将序列添加到索引中,形成多级序列inplace:是否返回在原序列上进行修改,默认否,返回一个新的序列verify_integrity:检查索引是否重复。默认是False3.数据预处理(将温度的后缀°C去掉)
# 所有行,bWendu列 bWendu列转为字符串,去除°C,然后转换为整形
df.loc[:, "bWendu"] = df["bWendu"].str.replace("°C", "").astype("int32")
df.loc[:, "yWendu"] = df["yWendu"].str.replace("°C", "").astype("int32")
4.使用单个label值查询数据
# 单元格 数据,得到一个具体的值
df.loc['2018-01-03', 'bWendu']
5.使用值列表批量查询
# 一行两列 数据,得到一个Series,即:1月3日的最高温度和最低温度
df.loc['2018-01-03', ['bWendu', 'yWendu']]
# 一列两行 数据,得到一个Series,即:1月3日和1月4日的最高温度
df.loc[['2018-01-03', '2018-01-04'], 'bWendu']
# 两行两列 数据,得到一个DataFrame
df.loc[['2018-01-03', '2018-01-04'], ['bWendu', 'yWendu']]
6.使用数值区间进行范围查询(区间包含开始,也包含结束,和列表有所不同)
# 行index区间
# 获取1月3号到1月6号的最高温度
df.loc['2018-01-03':'2018-01-06', 'bWendu']
# 列index区间
# 获取1月3号最高温度到风向的所有列
df.loc['2018-01-03', 'bWendu':'fengxiang']
# 行列都按区间查询
df.loc['2018-01-03':'2018-01-06', 'bWendu':'fengxiang']
7.使用条件表达式查询
# 查询最高温度大于10°C的天气数据
df.loc[df['bWendu'] > 10, :]
# 查询最高温度小于30°,并且最低温度大于15°,并且是晴天,并且天气为优的数据
df.loc[(df['bWendu'] < 30) & df['bWendu'] > 15) & df['tianqi'] == '晴') & df['aqiLevel'] == 1), :]
8.调用函数查询
def query_data(df):
return df.index.str.startswith('2018-09') & df['sqiLevel'] == 1
# 查询9月份,空气质量为优的数据
df.loc[query_data, :]
df.ilockdf.whereDataFrame.where(cond, other=nan, inplace=False, axis=None, level=None, errors='raise', try_cast=False, raise_on_error=None)
df.query直接赋值# 给所有行,增加一个温差列 值为最高温度减去最低温度
# df["bWendu"]是一个Series,两个Series相减,最终返回还是一个Series
df.loc[:, "wencha"] = df["bWendu"] - df["yWendu"]
df.apply沿着axis轴,将一个Series传递给一个函数,该函数对传递的Series进行处理,返回一个新的Series
axis=0代表横轴,即二维坐标系中的x轴,也就是行
axis=1代表纵轴,即二维坐标系中的y轴,也就是列
# 添加一列温度类型(如果最高温度大于33°就是高温;低于-10°就行就是低温;否则是常温)
def get_wendu_type(x):
if x["bWendu"] > 30:
return "高温"
if x["yWendu"] < -10:
return "低温"
return "常温"
df[:, "wendu_type"] = df.apply(get_wendu_type, axis=1)
# 对温度类型进行统计
df["wendu_type"].value_counts()
df.assign# 新增最高温度和最低温度对应的华氏温度列
df.assign(
# 新增的列名 x代表df
yWendu_huashi = lambda x : x["yWendu"] * 9 / 5 + 32
bWendu_huashi = lambda x : x["bWendu"] * 9 / 5 + 32
)
按条件选择分组分别赋值# 创建一个新列
df["wencha_type"] = ""
# 按条件选择,然后赋值给上面创建的列
df.loc[df["bWendu"] - df["yWendu"] > 10, "wencha_type"] = "温差大"
df.loc[df["bWendu"] - df["yWendu"] <= 10, "wencha_type"] = "温差正常"
数字列统计结果df.describe()

df["bWendu"].mean()
df["bWendu"].max()
df["yWendu"].min()
df['fengxiang'].unique()
df['tianqi'].unique()
df['fengli'].unique()
df['fengxiang'].value_counts()
X、Y同向变化,协方差越大说明同向程度越高X、Y反向变化,协方差越小说明反向程度越高df.cov()

# 可以看出空气质量指数aqi和空气质量等级aqiLevel相关性为0.94,非常的相关
df.corr()

# 空气质量和最高温度的相关系数
df["aqi"].corr(df["bWendu"]) # 0.077067
# 空气质量和最低温度的相关系数
df["aqi"].corr(df["yWendu"]) # 0.026513
# 空气质量和温差的相关系数
df["aqi"].corr(df["bWendu"] - df["yWendu"]) # 0.216522
isnull和notnull:检测是否是空值,可用于DataFrame和Seriesdropna:丢弃、删除缺失值axis:删除行还是列,{0 or ‘index’, 1 or columns},default 0how:如果等于any,则任何值为空都删除,如果等于all则所有值都为空才删除inplace:如果为True则修改当前df,否则返回新的df,默认返回新的fillna:填充空值value:用于填充的值,可以是单个值,或者字典(key是列名,value是值)method:等于ffill,使用前一个不为空的值填充forward fill,等于bfill,使后一个不为空的值填充backword fillaxis:按行还是列填充,{0 or ‘index’, 1 or columns}inplace:如果为True则修改当前df,否则返回新的df,默认返回新的
# 跳过前两行读取
studf = pd.read_excel('./data/study_excel.xlsx', skiprows=2)

studf.isnull()

studf["分数"].isnull()
studf.loc[studf["分数"].notnull(), :]

# 在元数据基础上删除全是空值的列
studf.dropna(axis="columns", how="all", inplace=True)

# 在元数据基础上删除全是空值的行
studf.dropna(axis="index", how="all", inplace=True)

studf.fillna({"分数": 0})
# 等同于
# studf.loc[:, "分数"] = studf['分数'].fillna(0)

# 使用前一个不为空的值进行填充
studf.loc[:, "姓名"] = studf["姓名"].fillna(method="ffill")

# index=False:去除索引列
studf.to_excel('./data/result_student.xlsx', index=False)


condition = df["ymd"].str.startswith("2018-03")
# 设置温差列(报错)
df[condition]["wencha"] = df["bWendu"] - df["yWendu"]
# 查看结果
df[condition].head()


df[condition]["wencha"] = df["bWendu"] - df["yWendu"]df.get("condition").set("wencha")get发出了报警,链式操做其实是两个步骤,先get后setget得到的dataframe可能是view(子df),也可能是copy(新的df),pandas发出警告。pandas的dataframe的修改写操做,只允许在源dataframe上进行get+set的两步操做,变成set的一步操做df.loc[condition, 'wen_cha'] = df["bWendu"] - df["yWendu"]
df[condition].head()

copy复制dataframedf_month3 = df[condition].copy()
df_month3[condition]["wencha"] = df["bWendu"] - df["yWendu"]
df_month3.head()

Pandas不允许先筛选子dataframe,再进行修改写入.loc实现一个步骤直接修改源dataframedataframe,再在该对象上进行修改写入Series排序Series.sort_values(ascending=True, inplace=False)
ascending:默认为True升序排序,False为降序排序inplace:修改原始数据还是复制一份新的数据df["bWendu"].sort_values()
DataFrame排序DataFrame.sort_values(by, ascending=True, inplace=False)
by:str或List,单列排序或者多列排序ascending:默认为True升序排序,False为降序排序inplace:修改原始数据还是复制一份新的数据df.sort_values(by='aqi')
df.sort_values(by=['bWendu', 'yWendu'], ascending=[True, False])
Series,再在str属性上调用函数
DataFrame上没有str属性和处理方法Series.str并不是python中的原生字符串,而是一套自己的方法,不过大部分和原生str很像object列都是字符串列,可以直接使用str的方法


1.获取Series的str属性
df["bWendu"].str
df["bWendu"].str.replace("°C", "")
df["bWendu"].str.isnumeric()
df["bWendu"].str.len()
condition = df["ymd"].str.startswith("2018-03")
df[condition].head()

df["ymd"].str.replace("-", "").str.slice(0, 6)
# df["ymd"].str.replace("-", "").str[0:6]
# 1.新增一列中文日期
def get_nianyueri(x):
year,month,day = x["ymd"].split("-)
return f"{year}年{month}月{day}日"
df["中文日期"] = df.apply(get_nianyueri, axis=1)
# 2.去掉中文日期这一列中的年月日中文字样
# 方法一:
df["中文日期"].str.replace("年", "").str.replace("月", "").str.replace("日", "")
# 方法二:
df["中文日期"].str.replace("[年月日]", "")
从上往下挤压从左往右挤压import pandas as pd
import numpy as np
df = pd.DataFrame(
np.arange(12).reshape(3,4),
columns=["A", "B", "C", "D"]
)
'''
A B C D
0 0 1 2 3
1 4 5 6 7
2 8 9 10 11
'''
df.drop("A", axis=1)
'''
B C D
0 1 2 3
1 5 6 7
2 9 10 11
'''
df.drop(1, axis=0)
'''
A B C D
0 0 1 2 3
2 8 9 10 11
'''
df.mean(axis=0)
'''
A 4.0
B 5.0
C 6.0
D 7.0
dtype: float64
'''
df.mean(axis=1)
'''
0 1.5
1 5.5
2 9.5
dtype: float64
'''
def get_sum_value(x):
return x["A"] + x["B"] + x["C"] + x["D"]
df["sum_value"] = df.apply(get_sum_value, axis=1)
'''
A B C D sum_value
0 0 1 2 3 6
1 4 5 6 7 22
2 8 9 10 11 38
'''
1.读取数据
import pandas as pd
fpath = './data/ratings.csv'
df = pd.read_csv(fpath)

2.设置索引
df.set_index("userId", inplace=True, drop=False)

3.使用索引查询
# 使用index查询
df.loc[500].head()
# 相当于
df.loc["userId" == 500].head()

Pandas会使用哈希表优化,查询性能O(1)O(logN)O(N)from sklearn.utils import shuffle
df_shuffle = shuffle(df)
# 检查索引是否是递增的
df_shuffle.index.is_monotonic_increasing # False
# 检查索引是否唯一
df_shuffle.index.is_unique # False
# 计时,查询 id=500的数据性能
%timeit df_shuffle.loc[500] # 498 µs ± 28.3 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
df_sorted = df_shuffle.sort_index()
# 检查索引是否是递增的
df_sorted .index.is_monotonic_increasing # True
# 检查索引是否唯一
df_sorted .index.is_unique # False
# 计时,查询 id=500的数据性能
%timeit df_sorted.loc[500] # 231 µs ± 13.7 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
import pandas as pd
s1 = pd.Series([1, 2, 3], index=list("abc"))
'''
a 1
b 2
c 3
dtype: int64
'''
s1 = pd.Series([2, 3, 4], index=list("bcd"))
'''
b 2
c 3
d 4
dtype: int64
'''
s1 + s2
'''
a NaN
b 4.0
c 6.0
d NaN
dtype: float64
'''
CategoricalIndex,基于分类数据的Index,提升性能MultiIndex,多维索引,用于groupby多维聚合后结果等DatetimeIndex,时间类型索引,强大的日期和时间的方法支持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, )
left:要merge的dataframe或seriesright:要merge的dataframe或serieshow:join类型,‘left’,‘right’,‘outer’,‘inner’on:join的key,left和right都要有这个keyleft_on:left的df或series的keyright_on:right的df或series的keyleft_index:使用index而不是普通的column做joinright_index:使用index而不是普通的column做joinsort:排序suffixes:合并表时重名字段自定义命名copyindicator1.用户对电影的评分数据:ratings.dat
import pandas as pd
df_ratings = pd.read_csv(
"./data/ratings.dat",
sep="::", # 分隔符为两个字符时会被识别为正则表达式,指定engine=python来告诉pandas他是一个字符串
engine="python",
names=["UserID", "MovieID", "Rating", "Timestamp"]
)

2.用户本身的信息数据:users.dat
df_users = pd.read_csv(
"./data/users.dat",
sep="::", #
engine="python",
names="UserID::Gender::Age::Occupation::Zip-code".split("::")
)

3.电影本身的数据:movies.dat
df_momvies = pd.read_csv(
"./data/movies.dat",
sep="::", #
engine="python",
names="MovieID::Title::Geners".split("::")
)

4.用户和评分join
df_ratings_users = pd.merge(
df_ratings, df_users, left_on="UserID", right_on="UserID", how="inner"
)

5.用户和评分join的结果再和电影join
df_ratings_movies = pd.merge(
df_ratings, df_momvies, left_on="MovieID", right_on="MovieID", how="inner"
)

one-to-one:关联的key都是唯一的one-to-many:左边key唯一,右边key不唯一many-to-many:左边右边key都不是唯一的1.数据表如下

2.合并
left = pd.DataFrame({
"sno": [11, 12, 13, 14],
"name": ["name_a", "name_b", "name_c", "name_d"]
})
right = pd.DataFrame({
"sno": [11, 12, 13, 14],
"age": ["21", "22", "23", "24"]
})
pd.merge(left, right, on="sno")


left = pd.DataFrame({
"sno": [11, 12, 13, 14],
"name": ["name_a", "name_b", "name_c", "name_d"]
})
right = pd.DataFrame({
"sno": [11, 11, 11, 12, 12, 13],
"grade": ["语文88", "数学90", "英语75", "语文66", "数学55", "英语29"]
})
pd.merge(left, right, on="sno")


left = pd.DataFrame({
"sno": [11, 11, 12, 12, 12],
"爱好": ["篮球", "羽毛球", "乒乓球", "篮球", "足球"]
})
right = pd.DataFrame({
"sno": [11, 11, 11, 12, 12, 13],
"grade": ["语文88", "数学90", "英语75", "语文66", "数学55", "英语29"]
})
pd.merge(left, right, on="sno")

left join、right join、inner join、outer join时数量的对齐关系
1.数据如下


left = pd.DataFrame({
"key": ["K0", "K1", "K2", "K3"],
"A": ["A0", "A1", "A2", "A3"],
"B": ["B0", "B1", "B2", "B3"]
})
right = pd.DataFrame({
"key": ["K0", "K1", "K4", "K5"],
"C": ["C0", "C1", "C2", "C3"],
"D": ["D0", "D1", "D2", "D3"]
})
2.inner join,默认,左右都有的key,才会出现在结果里
pd.merge(left, right, how='inner')

3.left join,左边的都会出现在结果里,右边匹配不到的以Null填充
pd.merge(left, right, how='left')

4.right join,右边的都会出现在结果里,左边匹配不到的以Null填充
pd.merge(left, right, how='right')

5.outer join,左边右边的都会出现在结果里,相互匹配不到的以Null填充
pd.merge(left, right, how='outer')

1.图示

2.使用suffixes默认值
pd.merge(left, right, on="key")

3.自定义重名的key
pd.merge(left, right, on="key", suffixes=("_left", "_right"))

concat语法pd.concat(objs, axis=0, join="outer", ignore_index=False)
objs:一个列表,内容可以是DataFrame或者Series,可以混合axis:默认是0,代表按行合并,如果等于1代表按列合并join:合并的时候索引的对齐方式,默认是outer join,也可以是inner joinignore_index:是否忽略掉原来的数据索引append语法df.append(other, ignore_index=False)
append只有按行合并,并没有按列合并,相当于concat按行合并的简写other:单个df、series、dict或者列表ignore_index:是否忽略掉原来的数据索引ExcelDataFrame添加行DataFrame添加列df1 = pd.DataFrame({
"A": ["A0", "A1", "A2", "A3"],
"B": ["B0", "B1", "B2", "B3"],
"C": ["C0", "C1", "C2", "C3"],
"D": ["D0", "D1", "D2", "D3"],
"E": ["E0", "E1", "E2", "E3"]
})
df2 = pd.DataFrame({
"A": ["A4", "A5", "A6", "A7"],
"B": ["B4", "B5", "B6", "B7"],
"C": ["C4", "C5", "C6", "C7"],
"D": ["D4", "D5", "D6", "D7"],
"F": ["F4", "F5", "F6", "F7"]
})


pd.concat([df1, df2])

ignore_index=True忽略原来的索引pd.concat([df1, df2], ignore_index=True)

join=inner过滤掉不匹配的列pd.concat([df1, df2], ignore_index=True, join="inner")

axis=1进行列合并pd.concat([df1, df2], axis=1)

s1 = pd.Series(list(range(4)), name='F')
pd.concat([df1, s1], axis=1)

# 添加行
s2 = pd.Series({i: i+str(4) for i in "ABCDE"}, name=4)
df1.append(s2)



df1 = pd.DataFrame(
[
[1, 2],
[3, 4]
],
columns=list("AB")
)
df2 = pd.DataFrame(
[
[5, 6],
[7, 8]
],
columns=list("AB")
)
df1添加一个名为df2的dataframedf1.append(df2)

df1.append(df2, ignore_index=True)

df = pd.DataFrame(
columns=["A"]
)

for i in range(5):
df = df.append({"A": i}, ignore_index=True)
df

pd.concat(
# 数据量过大时,需要分批
[pd.DataFrame([i], columns=["A"]) for i in range(5)],
ignore_index=True
)

import pandas as pd
df_source = pd.read_excel('./data/crazyant_blog_articles.xlsx')
df_source.head()
df_source.shape # (258, 3)

# 拆分列表
user_names = ['zs', 'ls', 'ww', 'zl', 'sq', 'qb']
# 获取总行数
total = df_source.shape[0]
# 计算每个人的任务条目
split_size = total // len(user_names)
if split_size % len(user_names) != 0:
split_size += 1
df_subs = []
for idx, user_name in enumerate(user_names):
# iloc的开始索引
begin = idx * split_size
# iloc的结束索引
end = begin + split_size
# 实现df按照iloc拆分
df_sub = df_source.iloc[begin:end]
# 将每个子df存入列表
df_subs.append((idx, user_name, df_sub))
for idx, user_name, df_sub in df_subs:
file_name = f"./split_dir/{idx}_{user_name}.xlsx"
df_sub.to_excel(file_name, index=False)
import os
excel_names = []
for excel_name in os.listdir('./split_dir'):
excel_names.append(excel_name)
df_list = []
for index, excel_name in enumerate(excel_names):
# 读取每个excel到df
excel_path = f"./split_dir/{excel_name}"
df_split = pd.read_excel(excel_path)
# 得到username
username = excel_name.replace(f"{index}_", "").split(".")[0]
# 每个df添加1列,用户名
df_split["username"] = username
print(df_split)
df_list.append(df_split)
pd.concat进行合并df_merge = pd.concat(df_list)
df_merge.shape # (258, 4)
df_merge.head()
df_mergr["username"].value_counts()


# index=False:忽略每个表中自己的索引
df_merge.to_excel(f"./split_dir/new_articles.xlsx", index=False)
import pandas as pd
import numpy as np
%matplotlib inline # 加这一句,能在jupyter notebook展示matplot图表
df = pd.DataFrame({
"A": ['foo', 'bar', 'foo', 'bar', 'foo', 'bar', 'foo', 'foo'],
"B": ['one', 'one', 'two', 'three', 'two', 'two', 'one', 'three'],
"C": np.random.randn(8),
"D": np.random.randn(8),
})

df.groupby('A').sum()

A变成了数据的索引列sum,但B列不是数字,所以被自动忽略掉foo和bar,然后计算foo和bar在C和D列对应的值加和后的结果df.groupby(['A', 'B']).mean()

('A', 'B')成对变成了二级索引df.groupby(['A', 'B'], as_index=False).mean()

df.groupby('A').agg([np.sum, np.mean, np.std])

df.groupby('A')['C'].agg([np.sum, np.mean, np.std])
# df.groupby('A').agg([np.sum, np.mean, np.std])['C']

df.groupby('A').agg({"C": np.sum, "D":np.mean})

df.groupby('A').agg({'C':[np.mean,'sum'],'D':['count',np.std]})

g = df.groupby("A")
for name, group in g:
print(name)
print(group)

g.get_group("bar")

g = df.groupby(["A", "B"])
for name, group in g:
print(name)
print(group)

g.get_group(('foo', 'two'))

for name, group in g['C']:
print(name)
print(group)
print(type(group))

import pandas as pd
fpath = "./data/beijing_tianqi_2018.csv"
df = pd.read_csv(fpath)
# 替换温度后面的 °C
df.loc[:, "bWendu"] = df["bWendu"].str.repace("°C", "").astype("int32")
df.loc[:, "yWendu"] = df["yWendu"].str.repace("°C", "").astype("int32")
df.head()

df["month"] = df["ymd"].str[:7]
df.head()

data = df.groupby("month")["bWendu"].max()

type(data) # pandas.core.series.Series
data.plot()

group_data = df.groupby("month").agg({"bWendu": np.max, "yWendu": np.min, "aqi": np.mean})

group_data.plot()


import pandas as pd
%matplotlib inline
stocks = pd.read_excel('./data/internet.xlsx')
stocks.shape # (12, 8)
stocks.head(3)

stocks['公司'].unique()
# array(["BIDU", "BABA", "IQ", "JD"], dtype=object)
stocks.index
# RangeIndex(start=0, stop=12, setp=1)
stocks.groupby("公司")["收盘"].mean()

ser = stocks.groupby(['公司', '日期'])["收盘"].mean()

ser.index

# 把二级索引变成列
ser.unstack()

ser.reset_index()

ser = stocks.groupby(['公司', '日期'])["收盘"].mean()

ser.loc["BIDU"]

#
ser.loc[("BIDU", "2019-10-02")]

#
ser.loc[:, "2019-10-02"]

stocks.head()

stocks..set_index(["公司", "日期"], inplace=True)

stocks.index

stocks.sort_index(inplace=True)

key1是索引的第一级,key2是索引的第二级,比如:key1=JD, key2=2019-10-02key1和key2是并列的同级索引,比如:key1=JD, key2=BABAstocks.loc["BIDU"]

stocks.loc[("BIDU", "2019-10-02"), :]

stocks.loc[("BIDU", "2019-10-02"), "开盘"]

stocks.loc[["BIDU", "JD"], :]

stocks.loc[(["BIDU", "JD"], "2019-10-03"), :]

stocks.loc[(["BIDU", "JD"], "2019-10-03"), "收盘"]

stocks.loc[("BIDU", ["2019-10-02", "2019-10-03"]), "收盘"]

# slice(None)代表筛选这一索引所有的内容
stocks.loc[(slice(None), ["2019-10-02", "2019-10-03"]), "收盘"]

stocks.reset_index()

map:只用于Series,实现每个值—>值的映射apply:用于Series实现每个值的处理,用于DataFrame实现某个轴的Series的处理applymap:只能用于DataFrame,用于处理该DataFrame的每个元素import pandas as pd
stocks = pd.read_excel("./data/internet.xlsx")
stocks.head()

stocks["公司"].unique()

dict_company_names = {
"bidu": "百度",
"baba": "阿里巴巴",
"iq": "爱奇艺",
"jd": "京东"
}
stocks["中文公司1"] = stocks["公司"].str.lower().map(dict_company_names)
stocks.head()

stocks["中文公司2"] = stocks["公司"].map(lambda x: dict_company_names[x.lower()])
stocks.head()

stocks["中文公司3"] = stocks["公司"].apply(lambda x: dict_company_names[x.lower()])
stocks.head()

stocks["中文公司3"] = stocks.apply(lambda x: dict_company_names[x["公司"].lower()], axis=1)
stocks.head()

x["公司"]获取公司这一列数据,然后进行处理sub_df = stocks[["收盘", "开盘", "高", "低", "交易量"]]
sub_df.head()

sub_df.applymap(lambda x: int(x))
sub_df

stocks.loc[:, ["收盘", "开盘", "高", "低", "交易量"]] = sub_df.applymap(lambda x: int(x))
stocks.head()


GroupBy(function)function的第一个参数是dataframefunction的返回结果,可以是dataframe、series、单个值,甚至和输入DataFrame完全没有关系
import pandas as pd
ratings = pd.read_csv(
"./data/ratings.dat",
sep="::",
engine="python",
names="UserID::MovieID::Rating::Timestamp".split("::")
)
ratings.head()

def ratings_norm(df):
min_value = df["Rating"].min()
max_value = df["Rating"].max()
df["Rating_norm"] = df["Rating"].apply(lambda x: (x - min_value) / (max_value - min_value))
return df
ratings = ratings.groupby("UserID").apply(ratings_norm)

ratings[ratings["UserID"] == 1].head()

TOPN数据fpath = "./data/beijing_tianqi_2018.csv"
df = pd.read_csv(fpath)
# 替换温度后面的 °C
df.loc[:, "bWendu"] = df["bWendu"].str.repace("°C", "").astype("int32")
df.loc[:, "yWendu"] = df["yWendu"].str.repace("°C", "").astype("int32")
# 增加一列月份
df["month"] = df["ymd"].str[:7]
df.head()

def getWenduTopN(df, topn):
"""
df: 每个月份分组group的df
"""
# df.sort_values(by="bWendu"):按高温一列升序排序
# [["ymd", "bWendu"]]:取年月日和高温两列数据
# [-topn:]:因为是升序,所以取-topn
return df.sort_values(by="bWendu")[["ymd", "bWendu"]][-topn:]
df.groupby("month").apply(getWenduTopN, topn=2).head()


电影评分数据集,每个月份的每个分数被评分多少次(月份、分数1-5、次数)import pandas as pd
import numpy as np
%matplotlib inline
df = pd.read_csv(
"./data/ratings.dat",
header=None,
sep="::",
engine="python",
names="UserID::MovieID::Rating::Timestamp".split("::")
)
df.head()

# 增加一列时间日期,由秒格式的Timestamp字段转换而来
df["pdate"] = pd.to_datetime(df["Timestamp"], unit="s")
df.head()

df.dtypes

# 按照月份和评分分组,创建两个索引,取Rating这个series,统计后倒序排列(方便验证结果)
df_group = df.groupby([df["pdate"].dt.month, "Rating"])["Rating"].agg({"pv": np.size}).sort_values("pdate", ascending=False)

df["month"] = df["pdate"].dt.month
df[(df["Rating"] == 5) & (df["month"]==12)]["Rating"].value_counts()
5 26760 Name: Rating, dtype: int64unstack实现透视df_stack = df_group.unstack()

df_stack.plot()

stack还原df_stack.stack().head()

pivot简化透视df_group.head(20)

df_reset = df_group.reset_index()
df_reset.head()

df_pivot = df_reset.pivot("pdate", "Rating", "pv")
df_pivot.head()

df_pivot.plot()

pivot:方法相当于对df使用set_index创建分层索引,然后使用unstackstack:DateFrame.stack(level=-1, dropna=True),将column变成index,类似把横放的书籍变成竖放
level:-1代表错层索引的最内层,可以通过0、1、2指定多层索引对应的层

