pandas是一个Python包,提供快速,灵活和富有表现力的数据结构,旨在既简单又直观的处理“关系”或“标记”数据。它旨在成为在Python中进行实际,真实世界数据分析的基本高级构建块。
pandas是一个开源的,BSD许可的库,为Python编程语言提供高性能,易于使用的数据结构和数据分析工具。
以下是pandas擅长的几件事:
DataFrame.head() and DataFrame.tail() 查看前几行,末尾几行
DataFrame.index or DataFrame.columns 查看行索引,列标签
DataFrame.to_numpy()给出了基础数据的NumPy表示形式,在输出中不包括索引或列标签;当DataFrame具有不同数据类型的列时,这可能是一项代价高昂的操作,
这归结为Pandas和NumPy之间的根本区别:NumPy数组在整个数组中具有一个dtype,而pandasDataFrame每列具有一个dtype。
当调用DataFrame.to_numpy()时,Pandas会找到可以容纳DataFrame中所有dtype的NumPy dtype。这可能最终成为对象需要将每个值转换为Python对象。
describe()显式数据的快速统计摘要:count、mean、std、min、25%、50%、75%、max
df.T转置数据,行列互换
DataFrame.sort_index()按轴排序:
DataFrame.sort_values()按值排序:
对于 df,所有浮点值和DataFrame.to_numpy()的DataFrame速度很快,不需要复制数据
对于 df2,具有多个 dtype 的DataFrame,DataFrame.to_numpy() 相对昂贵
建议使用优化的Pandas数据访问方法,DataFrame.at(),DataFrame.iat(),DataFrame.loc() 和 DataFrame.iloc()。
DataFrame.loc() or DataFrame.at()
标签获取单行全列,在多轴上按标签选取多行可选列,标签切片多行可选列,单行单列
获取标量值,快速获取标量值
获取标量
print(df.loc[dates[0], “A”])
快速获取标量,同上
print(df.at[dates[0], “A”])
DataFrame.iloc() or DataFrame.at()
按传递的整数,行列数组切片类似Numpy/Phthon,Numpy/Phthon类型的传递多个值list
显式切片行,显式切片列
显式获取值/快速获取
获取标量
print(df.iloc[1, 1])
快速访问标量,同上
df.iat[1, 1]
使用单个列的值来选择数据
从满足布尔条件的DataFrame中选择值(其他不满足的返回NaN)
使用isin()进行过滤
使用isin()进行过滤
设置新列会自动按索引对齐数据
通过标签及列设置值/通过下标位置设置值
通过NumPy array设置值
通过where条件设置值
通过标签及列设置值/通过下标位置设置值
通过NumPy array设置值
通过where条件设置值
Pandas主要使用值np.nan来表示缺失的数据。默认情况下,它不包含在计算中。
reindex重新编制索引允许更改/添加/删除指定轴上的索引。这将返回数据的副本
DataFrame.dropna() 丢弃有数据缺失的行
DataFrame.fillna(value=5) 过滤出Nan的数据并赋值5
isna() 获取NaN的布尔mask,为NaN返回True,否则False
DataFrame.fillna(value=5) 过滤出Nan的数据并赋值5
isna() 获取NaN的布尔mask,为NaN返回True,否则False
统计操作通常会排除丢失的数据。NaN与任何数运算得到NaN
执行描述性统计:df.mean()求均值
操作具有不同维度且需要对齐的对象。此外,Pandas会自动沿指定尺寸广播:
操作具有不同维度且需要对齐的对象。此外,Pandas会自动沿指定尺寸广播
DataFrame.apply() 对数据应用一个用户定义的方法
直方图和离散化(Histogramming and Discretization)
字符串方法
在str属性中配备了一组字符串处理方法,这些方法使对数组的每个元素进行操作变得容易,模式匹配通常默认使用正则表达式
pandas具有简单,强大且高效的功能,用于在频率转换期间执行重采样操作(例如,将第二次数据转换为5分钟数据)
Series.tz_localize() 将时间Series本地化为时区
Series.tz_convert() 将识别时区的时间Series转换为另一个时区
在Period和时间戳之间进行转换可以使用一些方便的算术函数。
Series.tz_localize() 将时间Series本地化为时区
Series.tz_convert() 将识别时区的时间Series转换为另一个时区
在时间跨度表示之间转换
在Period和时间戳之间进行转换可以使用一些方便的算术函数。在以下示例中将年度结束于 11 月的季度频率转换为季度结束后月底的上午 9 点:
Matplot pyplot绘制单图,多子图不同样式详解,这一篇就够了
Matplotlib三维绘图,这一篇就够了
import numpy as np
import pandas as pd
# 1. 对象创建
# 通过传递值列表来创建Series,让 pandas 创建默认整数索引
s = pd.Series([1, 3, 5, np.nan, 6, 8])
print(s)
# 使用Numpy及date_range日期Series创建DataFrame
dates = pd.date_range("20130101", periods=6)
print(dates)
df = pd.DataFrame(np.random.randn(6, 4), index=dates, columns=list("ABCD"))
print(df)
# 通过传递可转换为类似Serial结构的对象字典来创建DataFrame
df2 = pd.DataFrame(
{
"A": 1.0,
"B": pd.Timestamp("20130102"),
"C": pd.Series(1, index=list(range(4)), dtype="float32"),
"D": np.array([3] * 4, dtype="int32"),
"E": pd.Categorical(["test", "train", "test", "train"]),
"F": "foo",
}
)
print(df2)
print(df2.dtypes) # 列的类型
# 2. 查看数据
# DataFrame.head() and DataFrame.tail() 查看前几行,末尾几行
# DataFrame.index or DataFrame.columns 查看行索引,列标签
# DataFrame.to_numpy()给出了基础数据的NumPy表示形式,在输出中不包括索引或列标签;当DataFrame具有不同数据类型的列时,这可能是一项代价高昂的操作,
# 这归结为Pandas和NumPy之间的根本区别:NumPy数组在整个数组中具有一个dtype,而pandasDataFrame每列具有一个dtype。
# 当调用DataFrame.to_numpy()时,Pandas会找到可以容纳DataFrame中所有dtype的NumPy dtype。这可能最终成为对象需要将每个值转换为Python对象。
# describe()显式数据的快速统计摘要:count、mean、std、min、25%、50%、75%、max
# df.T转置数据,行列互换
# DataFrame.sort_index()按轴排序:
# DataFrame.sort_values()按值排序:
print(df.head(2))
print(df.tail(3))
print(df.index)
print(df.columns)
# 对于 df,所有浮点值和DataFrame.to_numpy()的DataFrame速度很快,不需要复制数据
# 对于 df2,具有多个 dtype 的DataFrame,DataFrame.to_numpy() 相对昂贵
print(df.to_numpy())
print(df2.to_numpy())
print(df.describe())
print(df.T)
print(df.sort_index(axis=1, ascending=False))
print(df.sort_values(by="B"))
# 3. 选择数据
## 3.1 获取行列
# 获取列:选择单个列,这将生成一个Series,等效于 df.A
# 获取行:切片[] (__getitem__), df[0:3] 同 df['2013-01-01':'2022-01-03']
print(df['A'])
print(df.A)
print(df[0:3])
print(df['2013-01-01':'2013-01-03'])
## 3.2 根据标签获取(根据标签/下标位置获取,差别在于标签前闭后闭,位置前闭后开)
# 建议使用优化的Pandas数据访问方法,DataFrame.at(),DataFrame.iat(),DataFrame.loc() 和 DataFrame.iloc()。
# DataFrame.loc() or DataFrame.at()
# 标签获取单行全列,在多轴上按标签选取多行可选列,标签切片多行可选列,单行单列
# 获取标量值,快速获取标量值
print(df.loc[dates[0]])
print(df.loc[:, ["A", "B"]])
print(df.loc["20130102":"20130104", ["A", "B"]])
print(df.loc["20130102", ["A", "B"]])
# 获取标量
print(df.loc[dates[0], "A"])
# 快速获取标量,同上
print(df.at[dates[0], "A"])
## 3.3 按下标位置获取(根据标签/下标位置获取,差别在于标签前闭后闭,位置前闭后开)
# DataFrame.iloc() or DataFrame.at()
# 按传递的整数,行列数组切片类似Numpy/Phthon,Numpy/Phthon类型的传递多个值list
# 显式切片行,显式切片列
# 显式获取值/快速获取
print(df.iloc[3])
print(df.iloc[3:5, 0:2])
print(df.iloc[[1, 2, 4], [0, 2]])
print(df.iloc[1:3, :])
print(df.iloc[:, 1:3])
# 获取标量
print(df.iloc[1, 1])
# 快速访问标量,同上
df.iat[1, 1]
## 3.4 布尔索引
# 使用单个列的值来选择数据
# 从满足布尔条件的DataFrame中选择值(其他不满足的返回NaN)
# 使用isin()进行过滤
print(df[df["A"] > 0])
print(df[df > 0])
# 使用isin()进行过滤
df2 = df.copy()
df2["E"] = ["one", "one", "two", "three", "four", "three"]
print(df2)
print(df2[df2["E"].isin(["two", "four"])])
## 3.5 设置
# 设置新列会自动按索引对齐数据
# 通过标签及列设置值/通过下标位置设置值
# 通过NumPy array设置值
# 通过where条件设置值
s1 = pd.Series([1, 2, 3, 4, 5, 6], index=pd.date_range("20130102", periods=6))
print(s1)
df["F"] = s1
print(df)
# 通过标签及列设置值/通过下标位置设置值
df.at[dates[0], "A"] = 0
df.iat[0, 1] = 0
# 通过NumPy array设置值
df.loc[:, "D"] = np.array([5] * len(df))
print(df)
# 通过where条件设置值
df2 = df.copy()
df2[df2 > 0] = -df2
print(df2)
# 4. 丢失数据
# Pandas主要使用值np.nan来表示缺失的数据。默认情况下,它不包含在计算中。
# reindex重新编制索引允许更改/添加/删除指定轴上的索引。这将返回数据的副本
# DataFrame.dropna() 丢弃有数据缺失的行
# DataFrame.fillna(value=5) 过滤出Nan的数据并赋值5
# isna() 获取NaN的布尔mask,为NaN返回True,否则False
df1 = df.reindex(index=dates[0:4], columns=list(df.columns) + ["E"])
df1.loc[dates[0]: dates[1], "E"] = 1
print(df1)
print(df1.dropna(how="any"))
# DataFrame.fillna(value=5) 过滤出Nan的数据并赋值5
print(df1.fillna(value=5))
# isna() 获取NaN的布尔mask,为NaN返回True,否则False
print(pd.isna(df1))
# 5. 运算符
# 统计操作通常会排除丢失的数据。NaN与任何数运算得到NaN
# 执行描述性统计:df.mean()求均值
# 操作具有不同维度且需要对齐的对象。此外,Pandas会自动沿指定尺寸广播:
print(df.mean()) # 按列
print(df.mean(1)) # 按行
s = pd.Series([1, 3, 5, np.nan, 6, 8], index=dates).shift(2)
print(s)
# 操作具有不同维度且需要对齐的对象。此外,Pandas会自动沿指定尺寸广播
print(df)
print(df.sub(s, axis="index"))
# DataFrame.apply() 对数据应用一个用户定义的方法
print(df.apply(np.cumsum))
print(df.apply(lambda x: x.max() - x.min()))
# 直方图和离散化(Histogramming and Discretization)
s = pd.Series(np.random.randint(0, 7, size=10))
print(s)
print(s.value_counts())
# 字符串方法
# 在str属性中配备了一组字符串处理方法,这些方法使对数组的每个元素进行操作变得容易,模式匹配通常默认使用正则表达式
s = pd.Series(["A", "B", "C", "Aaba", "Baca", np.nan, "CABA", "dog", "cat"])
print(s.str.lower())
# 5. 合并
# pandas提供了各种工具,可以在连接/合并类型操作的情况下,轻松地将Series和DataFrame对象与索引和关系代数功能的各种设置逻辑组合在一起。
# concat():将Pandas对象沿着一个轴连接在一起
# merge() 允许数据库join类型的合并,将多列结果组合
df = pd.DataFrame(np.random.randn(10, 4))
print(df)
# 切片
pieces = [df[:3], df[3:7], df[7:]]
print(pd.concat(pieces))
# 将列映射到DataFrame相对较快。但是添加行需要副本,并且可能很昂贵。建议将预先构建的记录列表传递给DataFrame构造函数,而不是通过迭代向其追加记录来生成DataFrame;
# merge() 允许数据库join类型的合并,将多列结果组合
left = pd.DataFrame({"key": ["foo", "foo"], "lval": [1, 2]})
right = pd.DataFrame({"key": ["foo", "foo"], "rval": [4, 5]})
print(left, right)
print(pd.merge(left, right, on="key"))
left = pd.DataFrame({"key": ["foo", "bar"], "lval": [1, 2]})
right = pd.DataFrame({"key": ["foo", "bar"], "rval": [4, 5]})
print(left, right)
print(pd.merge(left, right, on="key"))
# 6. 分组group
# "group by"指的是涉及以下一个或多个步骤的过程(Splitting Applying Combining):根据某些条件将数据拆分为多个组、将函数独立应用于每个组、将结果合并到数据结构中
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),
}
)
print(df)
print(df.groupby("A")[["C", "D"]].sum())
# 按多个列分组形成一个分层索引,再次应用 sum()
print(df.groupby(["A", "B"]).sum())
# 7. 分层索引和重塑(Hierarchical Indexing and Reshaping)
# stack() 方法“压缩”DataFrame列中的级别
# Pivot tables数据透视表
# pivot_table() 透视DataFrame,指定值、索引和列
tuples = list(
zip(
["bar", "bar", "baz", "baz", "foo", "foo", "qux", "qux"],
["one", "two", "one", "two", "one", "two", "one", "two"],
)
)
index = pd.MultiIndex.from_tuples(tuples, names=["first", "second"])
df = pd.DataFrame(np.random.randn(8, 2), index=index, columns=["A", "B"])
df2 = df[:4]
print(df2)
stacked = df2.stack()
print(stacked)
# 对于“stack”DataFrame或Series(以 MultiIndex 作为索引),stack() 的反运算是 unstack(),默认情况下,它取消堆叠最后一个级别
print(stacked.unstack())
print(stacked.unstack(1))
print(stacked.unstack(0))
# Pivot tables数据透视表
# pivot_table() 透视DataFrame,指定值、索引和列
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),
}
)
print(df)
print(pd.pivot_table(df, values="D", index=["A", "B"], columns=["C"])) # 透视还是比较复杂的,可以细看这个例子
# 8. 时间Series
# pandas具有简单,强大且高效的功能,用于在频率转换期间执行重采样操作(例如,将第二次数据转换为5分钟数据)
# Series.tz_localize() 将时间Series本地化为时区
# Series.tz_convert() 将识别时区的时间Series转换为另一个时区
# 在Period和时间戳之间进行转换可以使用一些方便的算术函数。
rng = pd.date_range("1/1/2012", periods=100, freq="S")
ts = pd.Series(np.random.randint(0, 500, len(rng)), index=rng)
print(ts.resample("5Min").sum())
# Series.tz_localize() 将时间Series本地化为时区
rng = pd.date_range("3/6/2012 00:00", periods=5, freq="D")
ts = pd.Series(np.random.randn(len(rng)), rng)
print(ts)
ts_utc = ts.tz_localize("UTC")
print(ts_utc)
# Series.tz_convert() 将识别时区的时间Series转换为另一个时区
print(ts_utc.tz_convert("US/Eastern"))
# 在时间跨度表示之间转换
rng = pd.date_range("1/1/2012", periods=5, freq="M")
ts = pd.Series(np.random.randn(len(rng)), index=rng)
print(ts)
ps = ts.to_period() # 年月日(日为月末最后一天)转年月
print(ps)
print(ps.to_timestamp()) # 转回年月日(日为月初第一天)
# 在Period和时间戳之间进行转换可以使用一些方便的算术函数。在以下示例中将年度结束于 11 月的季度频率转换为季度结束后月底的上午 9 点:
prng = pd.period_range("1990Q1", "2000Q4", freq="Q-NOV")
ts = pd.Series(np.random.randn(len(prng)), prng)
ts.index = (prng.asfreq("M", "e") + 1).asfreq("H", "s") + 9
print(ts.head())
# 9. 分类数据Categoricals
# 可以在DataFrame中包含分类数据
df = pd.DataFrame(
{"id": [1, 2, 3, 4, 5, 6], "raw_grade": ["a", "b", "b", "a", "a", "e"]}
)
# 转换raw_grade为category数据类型
df["grade"] = df["raw_grade"].astype("category")
print(df["grade"])
# 重命名类别名称
new_categories = ["very good", "good", "very bad"]
df["grade"] = df["grade"].cat.rename_categories(new_categories)
# 重新排序类别并同时添加缺少的类别(默认情况下,Series.cat()下的方法将返回一个新的系列)
df["grade"] = df["grade"].cat.set_categories(
["very bad", "bad", "medium", "good", "very good"]
)
print(df["grade"])
# 排序是按类别中的顺序排序的,而不是词法顺序
print(df.sort_values(by="grade"))
# 按分类列分组也会显示空类别
print(df.groupby("grade").size())
# 10. Plotting绘图
# plt.close()关闭图片窗口
# 在DataFrame上,plot()方法便于绘制带有标签的所有列:
import matplotlib.pyplot as plt
plt.close("all")
ts = pd.Series(np.random.randn(1000), index=pd.date_range("1/1/2000", periods=1000))
ts = ts.cumsum()
ts.plot()
plt.show()
df = pd.DataFrame(
np.random.randn(1000, 4), index=ts.index, columns=["A", "B", "C", "D"]
)
df = df.cumsum()
plt.figure()
df.plot()
plt.legend(loc='best')
plt.show()
# 11. 导入/导出数据
# DataFrame.to_csv() 写入csv
# pd.read_csv() 读取csv
# DataFrame.to_hdf() 写入hdf5
# pd.read_hdf("foo.h5", "df") 读取hdf5
# DataFrame.to_excel() 写入excel,设置sheet名字
# pd.read_excel() 读取excel,可设置读取的sheet名字
df.to_csv("foo.csv")
print(pd.read_csv("foo.csv"))
df.to_hdf("foo.h5", "df")
print(pd.read_hdf("foo.h5", "df"))
df.to_excel("foo.xlsx", sheet_name="Sheet1")
print(pd.read_excel("foo.xlsx", "Sheet1", index_col=None, na_values=["NA"]))