pandas指令整理
本文旨在记录自己学习过程中遇到的一些常见代码,日后会进行日常维护,如果有幸被同样在学习的朋友看到还请批评指正。如果碰巧对你提供了一些帮助,那我也荣幸万分。
pandas中的常用数据有两种类型,一维的series,二维的DataFrame。
Series
1.创建series
pd.series(data=None, index=None, dtype=None, name=None, copy=False, fastpath=False)
import pandas as pd
a = pd.Series([1, 2, 3, 4, 5, 6, 7])
print(a)
打印结果如下
左侧一列是行号,右侧一列是我们输入的内容.
下面添加索引index
a = pd.Series([1, 2, 3, 4, 5, 6, 7], index=list("abcadef"))
print(a)
即行号是可以自定义的,不过自定义的行号的个数要与传入数据个数相同。
通过字典也可以创建series
dict = {"a": 1, "b": 2, "c": 3, "d": 4}
a = pd.Series(dict)
print(a)
其效果和指定内容和索引的效果相同。
下面是通过一个推导式创建字典,再生成series的操作
import string
dict = {string.ascii_uppercase[i]: i for i in range(10)}
b = pd.Series(dict)
print(b)
2.索引
可以直接通过索引键(这里借鉴字典中的说法)来找到该键对应的值。
print(a["a"])
print(b["B"])
可以通过指令a.index()获取series的所有键。
print(a.index)
for i in a.index:
print(i)
print(list(a.index))
打印效果分别如下图所示。
同样,也可以获取series的所有值
print(a.values)
print(list(a.values))
结果分别如下:
series与ndarray具有相同的操作方式,可以进行同样的切片操作。
DataFrame
import pandas as pd
import numpy as np
DataFrame是二维的,可以看做是series的容器。
1.创建DataFrame
pd.DataFrame(data=None,index: Optional[Axes] = None,columns: Optional[Axes] = None,dtype: Optional[Dtype] = None,copy: bool = False,)
a = pd.DataFrame(np.arange(0, 18).reshape(3, 6)) # 使用默认行列号创建
print(a)
a = pd.DataFrame(np.arange(0, 18).reshape(3, 6), index=list("abc"), columns=list("ABCDEF")) # 指定行列号创建
print(a)
如果不指定index(行号)和columns(列号)的话,则会默认设置为从0开始的数字。
指定行列号的效果如下。
通过字典生成DataFrame
一个键可以对应一个值列表,可以将一个键看做一列数据的属性名称。
dict1 = {"a": [1, 2], "b": [2, 2], "c": [4, 5]}
d1 = pd.DataFrame(dict1)
print(d1)
同样也可以分别创建包含各个键的字典,分别赋值,效果与上面的方法相同。
dict2 = [{"a": 2, "b": 5, "c": 4, "d": 5}, {"a": 5, "b": 2, "c": 5, "d": 8}, {"a": 4, "b": 6, "c": 5}]
d2 = pd.DataFrame(dict2)
print(d2)
如果在生成DataFrame时出现缺项,则计算机会自动用nan填充。如上图。
2.DataFrame的属性
(1) index
.index指令可以获取行号,如果行号是连续数字的话,则会返回行号的起点,终点和步长。如果是字符则会返回所有行号。
print(d2.index)
print(a.index)
(2)values
.values可以返回包含所有值的ndarray
print(d2.values)
(3) columns
.columns可以返回所有的列号
print(d2.columns)
(4)shape尺寸
.shape指令可以返回Dataframe的尺寸。
print(d2.shape)
(5)dtypes数据类型
.dtypes可以返回数据类型
print(d2.dtypes)
会按照列号逐列返回。
(6)维度
.ndim可以返回Dataframe的维度
print(d2.ndim)
(7)前n行元素
.head(n)可以返回前n行元素,默认为前5行,可以结合排序指令筛选数据
print(d2.head(2))
(8)后n行元素
.tail(n) 可以返回后n行元素,默认为后5行
print(d2.tail(2))
(9)详细信息
.info(), .describe()
以上两个指令均可返回dataframe的详细信息。返回结果略有不同。
.info()会返回所有的列号,每一列的数据个数和数据类型,还会返回当前dataframe占用的内存空间。
print(d2.info())
.describe()指令会返回列号,每一列的数据个数,以及该列数据的均值,方差等统计学数据。
print(d2.describe())
(10)排序
.sort_values(by,axis=0,ascending=True,inplace=False,kind=“quicksort”,na_position=“last”, ignore_index=False, key: ValueKeyFunc = None,)
这个指令可以对dataframe进行排序,主要会用到前两个参数:
by:指定按照哪一列的列号进行排序。
ascending:是否降序
按照a列降序排序
print(d2)
d2 = d2.sort_values(by="a")
print(d2)
按照a列升序排序
d2 = d2.sort_values(by="a", ascending=False)
索引
可以通numpy中的索引方式一样,进行切片操作。
d2 = pd.DataFrame(dict2)
print(d2[:2]) # 取行
print(d2["a"]) # 取列
print(d2[:2]["a"]) # 取行和列
可以使用.loc指令按照行列号索引。
print(a)
print(a.loc["c", "A"]) # 取c行A列的元素
print(a.loc["c"]) # 取c行的元素
print(a.loc[:, "A"]) # 取A列的元素
print(a.loc[["c", "b"]]) # 取多行
print(a.loc[:, ["B", "D"]]) # 取多列
print(a.loc[["c", "b"], ["B", "D"]]) # 取多行和多列的交叉部分
print(a.loc[["c", "b"], "B":"D"]) # 取多行和连续多列,这里与位置索引不同的是可以取到:后面那个列号。
使用.iloc指令按位置索引
print(a.iloc[1]) # 第一行
print(a.iloc[1:3]) # 取1-2行,这里可以看到,是取不到:后面那个数字的。
print(a.iloc[1, 4]) # 取1行4列元素
print(a.iloc[1, [3, 5]]) # 取第一行第3,5两列的元素
print(a.iloc[1, 3:5]) # 取第1行,3,4,两列的元素
a.iloc[1, 3:5] = 10 # 可以进行赋值操作
print(a)
a.iloc[1, 3:5] = np.nan # 可以赋值为nan
print(a)
布尔索引:
print(a[a > 5])
print(a[(a["A"] > 5)]) # 只能索引列,不能索引行,按照第A列进行索引,如果符合条件,则这个元素所在的行被保留
print(a[(a["A"] > 5) | (a["E"] < 10)]) # 不同条件用小括号括起来,中间加逻辑与&或逻辑或|
处理nan数据
print(a.isnull()) # 逐个元素判断是否为nan
print(a.notnull()) # 逐个元素判断是否不是nan
'''
删除nan所在的行列
“how”默认为any,只要有任意一个为nan就删除其所在的行列。若为“all"则仅当当前行或列全部为nan时才删除
inplace:表示替换,原地修改。
'''
c = a.dropna(axis=1, how="any", inplace=False)
b = a
c = b.dropna(axis=1, how="any", inplace=True)
print(c)
print(b)
如果inplace是True,那么经过dropna操作以后,改变的将是a本身,不会有返回值。
c = a.dropna(axis=1, how="all", inplace=False) # how是all,那么只有该列全是nan时才删除,所以结果没有删除任一列
print(c)
a.loc["a", ["B", "C"]] = np.nan
d = a.fillna(666) # 将dataframe中为nan的数据用给定值填充,这个值一般不会简单设定,而是用均值或其他统计学运算后的数据进行填充,这里仅仅是做个示意
print(d)
读取外部数据
pd.read_csv() # 读取外部csv文件
pd.read_excel() # 读取外部excel文件
pd.read_sql(sql_sentence, connection) # 读取外部mysql或mongodb数据库文件
pd.read_clipboard() # 读取剪切板文件
打印显示所有数据
转载自:https://blog.csdn.net/qq_17753903/article/details/84947089
#显示所有列
pd.set_option('display.max_columns', None)
#显示所有行
pd.set_option('display.max_rows', None)
#设置value的显示长度为100,默认为50
pd.set_option('max_colwidth',100)
数据合并
按行合并join()
df1 = pd.DataFrame(np.linspace(0, 9, 10).reshape(2, 5), index=["1", "2"], columns=list("abcde"))
df2 = pd.DataFrame(np.ones((3, 3)), index=["x", "z", "y"], columns=list("123"))
print(df1)
print(df2)
print("*"*100)
print(df1.join(df2))
print("*"*100)
print(df2.join(df1))
# join()指令,按行号拼接,将对应行号的元素进行合并
# 合并后的行数以前边的为准,如上例,前面数据行数为2,那么合并后行数为2,多余的行删除
# 前面数据行数为3,那么合并后的行数为3,如果后边的数据不足三行,那么多出了的一行用nan补全。
上面这个例子中两组数据的行号均不相同,df1行号是"1", “2”,df2的行号是"x", “z”, “y”。下面对df1的行号进行一下修改,再运行相同的程序。
df1 = pd.DataFrame(np.linspace(0, 9, 10).reshape(2, 5), index=["x", "z"], columns=list("abcde"))
df2 = pd.DataFrame(np.ones((3, 3)), index=["x", "z", "y"], columns=list("123"))
print(df1)
print(df2)
print("*"*100)
print(df1.join(df2))
print("*"*100)
print(df2.join(df1))
由上面的例子可见,按行拼接,以其前边的数据为准,后边的数据存在相同的行号则合并,如果不存在相同的行号则用nan补全。
按列合并merge()
(1)内连接
merge()指令按照列号连接(内连接)
a.merge(b,on(“column”))结果是将b按照给定的列号“column”进行连接。
具体操作步骤:逐个判断b的column列上的元素有没有与a中对应列上的元素相等
如果相等,则将这个元素对应的行和a中那个元素对应的行进行拼接,拼接过后的行包含a,b两个数据所有的列号,取的是并集。
df1 = pd.DataFrame(np.linspace(0, 9, 10).reshape(2, 5), index=["1", "2"], columns=list("abcde"))
df3 = pd.DataFrame(np.zeros((3, 3)), index=["x", "z", "y"], columns=list("adf"))
print(df1)
print(df3)
print("*"*100)
print(df1.merge(df3, on="a"))
print("*"*100)
print(df1.merge(df3, on="d"))
从上图我们可以看出,对df1和df3按照a列合并,df1中的第a列的第一个元素和df3中的第a列的第1个元素相等,则这个元素对应的行进行拼接,取并集,注意图中出现了d_x和d_y这两列,不要将这里的x,y和df3的行号弄混,这里d_x指的是第一个数据(df1)中的d列,d_y指的是第二个数据(df3)中的d列,因为两组数据存在了相同的列号,为了便于区分才这样写的。
当按照d列拼接时,因为df1中的d列和df3中的d列没有元素相同,所以最后得到的是空的DF。
那么将指令稍作修改:
print(df1)
print(df3)
print("*"*100)
print(df3.merge(df1, on="a"))
结果如下,修改了merge()指令前后数据的位置,输出结果中数据列号的位置也会跟着调换。
(2)外连接
print(df1)
print(df3)
print("*"*100)
print(df1.merge(df3, on="a", how="outer"))
print("*"*100)
print(df1.merge(df3, on="d", how="outer"))
print("*"*100)
print(df3.merge(df1, on="a", how="outer"))
可以看到,仍然会进行对比的操作,与上面内连接不同的地方就在与即使指令前面的数据中指定列的元素与后边的数据中对应列上的元素都不相等,也会将两组数据拼接在一起,不会删除数据,缺失数据的地方用nan补齐。
(3)左右连接
左右连接就是将参数how设置为“left”或“right”
a.merge(b,on(“column”), how=“left”)(左连接)以左边的数据为准,左边有的行都有,左边没有的就没有
a.merge(b,on(“column”), how=“right”)(右连接)以右边的数据为准,右边有的行都有,右边没有的就没有
左连接:
print(df1)
print(df3)
print("*"*100)
print(df1.merge(df3, on="a", how="left"))
print("*"*100)
print(df1.merge(df3, on="d", how="left"))
print("*"*100)
print(df3.merge(df1, on="a", how="left"))
右连接:
print(df1)
print(df3)
print("*"*100)
print(df1.merge(df3, on="a", how="right"))
print("*"*100)
print(df1.merge(df3, on="d", how="right"))
print("*"*100)
print(df3.merge(df1, on="a", how="right"))
按照不同列合并
当出现列号都不相同时,可以使用a.merge(b,left_on(“column1”), right_on(“column2”))使a的column1列和b的column2列进行比较合并。
print(df1)
print(df3)
print("*"*100)
print(df1.merge(df3, left_on="a", right_on="d")
print("*"*100)
print(df1.merge(df3, left_on="a", right_on="d")
print("*"*100)
print(df3.merge(df1, left_on="a", right_on="d")
就是将前面的数据指定列和后面的数据指定列进行对比,不再是对比列号相同的列。同样可以进行内连接,外连接,左右连接的选择。