数据处理很多需要用到pandas,有两个基本类型:Series表示一维数据,DataFrame表示多维。以下是一些常用方法的整理:
pandas.Series
创建 Series
pandas.Series( data, index, dtype, copy)
name | value |
---|---|
data | 数据采取各种形式,如:ndarray,list,dict, constants(常量) |
index | 索引值必须是唯一的和散列的,与数据的长度相同。 默认np.arange(n)如果没有索引被传递。 |
dtype | dtype用于数据类型。如果没有,将推断数据类型 |
copy | 复制数据,默认为false。 |
- 指定了
dtype=float
后,如果value中有字符串,则尝试转换,如果转换失败,则报错 - index 的类型可以瞎写
- 指定index后,会强行改变已有的index的顺序,如果指定的index中有新的项,则该行的值为NaN
# 创建空series
s = pd.Series()
print(s)
# 使用ndarray创建
## index与array维度需要一致,否则会报错
s2 = pd.Series(np.arange(0,5), index=['a',2,'c',1, 2.2], dtype=float)
print("
s2:
", s2)
# 使用list创建
s3 = pd.Series([1,2,"10",4,5], index=['a',1,'c','d', 2.2], dtype=float)
print("
s3:
", s3)
# 使用字典创建
## 字典的建的顺序会被index改变, key变成了行,一维数组,只有行
s4 = pd.Series({'a':1, 'b':2, 'c':3}, index=['b', 'c', 'a', 'd'])
print("
s4:", s4)
# 使用常量创建
s5 = pd.Series(10, index=[1,2,3,4,5])
print("
s5:", s5)
# 执行结果如下:
Series([], dtype: float64)
s2:
a 0.0
2 1.0
c 2.0
1 3.0
2.2 4.0
dtype: float64
s3:
a 1.0
1 2.0
c 10.0
d 4.0
2.2 5.0
dtype: float64
s4: b 2.0
c 3.0
a 1.0
d NaN
dtype: float64
s5: 1 10
2 10
3 10
4 10
5 10
dtype: int64
访问数据
s2.a
,s2['a']
,s2[:]
,s2[[0,1,2]]
,s2[['a',1,'c',2,2]]
- 访问数据时,index默认是数字,如果手动指定的index也是数字,那么
s[[0,1,2,3,4]]
指的是手动指定的index的值
使用index
和 values
可以访问索引和值,talk is cheap, code as follow:
print(type(a.index), " : ", a.index)
print(type(a.index.values), " : ", a.index.values)
print(type(a.values), " : ", a.values)
# <class 'pandas.core.indexes.range.RangeIndex'> : RangeIndex(start=0, stop=10, step=1)
# <class 'numpy.ndarray'> : [0 1 2 3 4 5 6 7 8 9]
# <class 'numpy.ndarray'> : [10 11 12 13 14 15 16 17 18 19]
Series的布尔索引
对于numpy,索引可以这样用
a = np.arange(10)
a>5 # [False False False False False False True True True True]
type(a>5) # <class 'numpy.ndarray'>
a[a>5] # [6 7 8 9]
对于pandas,用法也一样:
a = pd.Series(np.arange(10, 20))
print(a>15)
print(type(a>15))
print(a[a>15])
结果如下:
0 False
1 False
2 False
3 False
4 False
5 False
6 True
7 True
8 True
9 True
dtype: bool
<class 'pandas.core.series.Series'>
6 16
7 17
8 18
9 19
dtype: int32
pandas.DataFrame
创建 DataFrame
pandas.DataFrame( data, index, columns, dtype, copy)
数据可以采取各种形式,如:ndarray
,series
,map
,lists
,dict
,constant
和另一个DataFrame
- 一行或者一列数据,最终都是Series类型
- DataFrame([a,b,c,...]) 用一维列表创建的DataFrame是列向量
- 用.T可以转置DataFrame
# 空
df = pd.DataFrame()
# 列表
## 任意维度不服都会报错
df2 = pd.DataFrame([[1,2,3],[4,5,'a']], index=['one','two'], columns=['a', 'b', 'c'], dtype=float)
# 含有列表的字典
## key变成了 列
## columns区分大小写,如果columns在keys中没有出现,就是NaN
## 如果columns与map维度不对也不会报错,没有的数据用NaN填充
## index与map维度不对就会报错。
df3 = pd.DataFrame({'Name':['Tom', 'Jack', 'Steve', 'Ricky'],'Age':[28,34,29,42]}, index=[2,3,4,5], columns=['Age', 'Name'])
# 含有字典的列表
## 字典的key总是作为列
## 再Series中一个字典可以创建一条Series,这里多个字典,可以认为是多个Series
# 用字典列表创建DataFrame如果字典的clolum不一致,不会报错,会取并集
df4 = pd.DataFrame([{'a': 1, 'b': 2},{'a': 5, 'b': 10, 'c': 20}], index=[0,1], columns=list("abc"))
# 系列Series
### 骚操作,series当成list,就和用包含列表的字典那个情况一样了。
df5 = pd.DataFrame({'one': pd.Series(np.arange(0,5)), 'two': pd.Series(np.arange(10,15))})
# 转置
df5.T
df: df2:
Empty DataFrame a b c
Columns: [] one 1.0 2.0 3
Index: [] two 4.0 5.0 a
df3: df4:
Age Name a b c
2 28 Tom 0 1 2 NaN
3 34 Jack 1 5 10 20.0
4 29 Steve
5 42 Ricky
df5: df5.T:
one two 0 1 2 3 4
0 0 10 one 0 1 2 3 4
1 1 11 two 10 11 12 13 14
2 2 12
3 3 13
4 4 14
常见方法
常见方法:
-
df.shape
: (行数,列数) -
df.dtypes
: 列数据类型(骚操作) -
df.ndim
: 数据维度 -
df.index
: 行索引 -
df.columns
: 列索引 -
df.values
: 对象值,二维ndarray数组 -
df.T
:DataFrame
的转置,类似二维数组的转置 -
df.head(3)
#显示头部几行,默认5行 -
df.tail(3)
#显示末尾几行,默认5行 -
df.info()
#相关信息概览:行数,列数,列索引,列非空值个数,列类型,列类型,内存占用 -
df.describe()
#快速综合统计结果:计数,均值,标准差,最大值,四分位数,最小值
print(df5)
print(df5.shape)
print(df5.ndim)
print("df5.index: ", type(df5.index), " ", df5.index)
print("df5.columns:", type(df5.columns), " ", df5.columns)
print("df5.values:", type(df5.values), " ", df5.values)
print(df5.head(2))
print(df5.tail(2))
df5.info()
df5.describe()
one two
0 0 10
1 1 11
2 2 12
3 3 13
4 4 14
(5, 2)
2
df5.index: <class 'pandas.core.indexes.range.RangeIndex'> RangeIndex(start=0, stop=5, step=1)
df5.columns: <class 'pandas.core.indexes.base.Index'> Index(['one', 'two'], dtype='object')
df5.values: <class 'numpy.ndarray'>
[[ 0 10]
[ 1 11]
[ 2 12]
[ 3 13]
[ 4 14]]
# head()
one two
0 0 10
1 1 11
# tail()
one two
3 3 13
4 4 14
# info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 5 entries, 0 to 4
Data columns (total 2 columns):
one 5 non-null int32
two 5 non-null int32
dtypes: int32(2)
memory usage: 120.0 bytes
# describe()
one two
count 5.000000 5.000000
mean 2.000000 12.000000
std 1.581139 1.581139
min 0.000000 10.000000
25% 1.000000 11.000000
50% 2.000000 12.000000
75% 3.000000 13.000000
max 4.000000 14.000000
排序
df.sort_values(by="xxxx", axis="index", ascending=False, inplace=False)
- axis: 表示对行还是对列排序。对行排序(
axis=0
或axis="index"
), 对列排序(axis=1
或axis="columns
") - by : 表示按照这个属性排序。如果
axis=0
,则这里应该填columns中的一个;如果axis=1
, 则这里应该填index中的一个 - ascending: True-升序,False-降序
- inplace: 是否替换原来的DataFrame
- 如果需要按照多个值排序,将写成
by=['a','b']
即可
# 排序
df = pd.DataFrame(np.random.randint(20, size=(4,5)).reshape(4, 5), index=list("abcd"), columns=list("xyzmn"))
## 按行排序
df = df.sort_values(by="x", axis="index", ascending=False)
# df = df.sort_values(by="x", axis=0, ascending=False) # axis=0 与 axis="index" 等价
## 按列排序
# df = df.sort_values(by="a", axis=1, ascending=True)
## 多值排序
df.iloc[0,2] = 2
df.sort_values(by=['a', 'b'], axis="columns", ascending=True, inplace=True)
# 按行排序 # 多值排序
n z y m x n z y m x
a 2 2 4 13 17 a 2 2 2 13 17
d 13 7 12 11 13 d 13 7 12 11 13
c 16 1 6 14 7 c 16 1 6 14 7
b 1 7 18 19 3 b 1 7 18 19 3
访问(索引)
df[locs]
df[col]
一般用于选择列,[]
中写列名。手动指定columns防止和index 冲突df[["col". "col"...]]
: 表示选择多列- (1)
df[num]
中为数字时,默认选择行,且只能进行切片的选择,不能单独选择(df[0]
); (2)就算只返回一行,返回类型也是DataFrame
; (3)不可以用用手动指定的index字符串访问行。 - 如果只返回一列数据,那么是Series类型;如果返回多列数据,一个Series无法保存,返回的是
DataFrame
类型
df = pd.DataFrame(np.random.randint(20, size=(4,5)).reshape(4, 5), index=list("abcd"), columns=list("xyzmn"))
print(df)
# df[col]一般用于选择列,[]中写列名。手动指定columns防止和index 冲突
print(type(df["x"]), " ", df["x"])
print(type(df[["x", "y"]]), " ", df[["x", "y"]])
print(type(df[:1]))
x y z m n
a 12 4 0 18 8
b 1 17 12 8 14
c 4 10 11 14 4
d 19 19 5 2 18
<class 'pandas.core.series.Series'>
a 12
b 1
c 4
d 19
Name: x, dtype: int32
<class 'pandas.core.frame.DataFrame'>
x y
a 12 4
b 1 17
c 4 10
d 19 19
<class 'pandas.core.frame.DataFrame'>
df.loc[]
全是字符串,可以用切片,切片是闭区间。可以选择一行的某些列或者多行多列
- 一样多列 & 多行一列 都是Series, 除非遇到
df.loc[['a'], ['x', 'y']]
他是DataFrame
类型的,但是['a']
把[]
去掉就变成Series了 df.loc[0, "one"]
: loc的第一个下标可以写数字,第二个下标必须写字符串
# df.loc[]
print(df)
print(df.loc["a"]) # Series
print(df.loc["a", "y"]) # int32
print(df.loc["a":, "y"]) # Series,多行一列, 一行多列也是Series
print(df.loc["a":, "y":]) # DataFrame 多行多列
print((df.loc[['a', 'b'],['x', 'y']])) # DataFrame多行多列
print(type(df.loc[['a', 'b'], 'x'])) # df.loc[['a', 'b'], 'x']返回Series, 但是 df.loc[['a', 'b'], ['x']]返回DataFrame
print(type(df.loc[['a'], ['x', 'y']])) # 与上例一样
# 它对于没有指定index 和columns 来说,就是垃圾了
# df2 = pd.DataFrame(np.random.randint(20, size=(4,5)).reshape(4, 5))
# print(df2["0", "0"])
x y z m n
a 12 4 0 18 8
b 1 17 12 8 14
c 4 10 11 14 4
d 19 19 5 2 18
x 12
y 4
z 0
m 18
n 8
Name: a, dtype: int32
4
a 4
b 17
c 10
d 19
Name: y, dtype: int32
y z m n
a 4 0 18 8
b 17 12 8 14
c 10 11 14 4
d 19 5 2 18
x y
a 12 4
b 1 17
<class 'pandas.core.series.Series'>
<class 'pandas.core.frame.DataFrame'>
特殊情况:当df的行标签或者列标签是数字时, loc[]后面也可以使用数字访问:
dfx = pd.DataFrame(np.random.randint(20, size=(4,5)).reshape(4, 5))
print(dfx.loc[0]) # 第0行
print(dfx.loc[:, 0]) # 第0列
dfx.index = list("abcd")
# print(dfx.loc[0]) # 第0行: cannot do label indexing on <class 'pandas.core.indexes.base.Index'> with these indexers [0] of <class 'int'>
print(dfx.loc["a"]) # 第0行
print(dfx.loc["a":, 0]) # 第0列
# df # 第0行 # 第0列
0 1 2 3 4 0 1 0 1
0 1 0 4 5 2 1 0 1 3
1 3 15 10 14 14 2 4 2 8
2 8 4 5 4 3 3 5 3 17
3 17 5 10 19 16 4 2 Name: 0, dtype: int32
Name: 0, dtype: int32
# dfx.index = list("abcd")
0 1 2 3 4
a 1 0 4 5 2
b 3 15 10 14 14
c 8 4 5 4 3
d 17 5 10 19 16
# 第0行 # 第1行
0 1 a 1
1 0 b 3
2 4 c 8
3 5 d 17
4 2 Name: 0, dtype: int32
Name: a, dtype: int32
df.iloc[]
用索引访问,用法类似
布尔索引
df > x
: 会返回一个布尔矩阵df["col_name"] > x
: 返回Series,表示一列的布尔值df[df["col_name"]>x]
: 用上面的一列的Series,选择满足条件的行df[(df["col_name"] > x) & (df["col_name"] <y)]
: 多个条件需要用括号分别括起来,逻辑关系用& |
表示
# 索引
df = pd.DataFrame(np.arange(0,20).reshape(4,5), columns=["one", "two", "three", "four", "five"])
print(df)
print(df[df["one"]>2]) # 如果有NaN,则,跳过该值
print(df[[True, False, True, False]]) # 也可以直接手动指定
print(df[df["two"]==5]["two"])
print(df[(df["two"]>4) & (df["two"]<7) ]) # 多个条件之间用&或者|连接,条件需要用括号括起来
# 字符串函数
print(df)
df = df.astype(str)
print(df[(df['one'].str.len()>1) & (df['one'].str.len()<6)]) # 可以根据字符串判断
print(type(df['one'].str.len()>1))
one two three four five
0 0 1 2 3 4
1 5 6 7 8 9
2 10 11 12 13 14
3 15 16 17 18 19
# df[df["one"]>2]
one two three four five
1 5 6 7 8 9
2 10 11 12 13 14
3 15 16 17 18 19
# df[[True, False, True, False]]
one two three four five
0 0 1 2 3 4
2 10 11 12 13 14
# df["two"]==5]["two"]
Series([], Name: two, dtype: int32)
# df[(df["two"]>4) & (df["two"]<7) ]
one two three four five
1 5 6 7 8 9
# df 添加一行
one two three four five
0 0 1 2 3 4
1 5 6 7 8 9
2 10 11 12 13 14
3 15 16 17 18 19
4 twilight abc abcdefghijklmn a shflksahfkshadkfhasdkhfksh
one two three four five
2 10 11 12 13 14
3 15 16 17 18 19
<class 'pandas.core.series.Series'>
处理空值
isnull()
,notnull()
: 返回一个bool矩阵dropna (axis=0, how='any', inplace=False)
: 删除空值axis=1
表示删除所在列,axis=0
表示删除所在行- how可取值 any 或者 all,表示一行只有一个Nan就删除,或者是一行全是NaN就删除
t.fillna(t.mean())
: 填充NaN;mean()计算所有列的平均值,当存在NaN元素时,计算mean会跳过这个元素,就相当于少了一个元素一样。
操作
操作
- 如果想要将两个不等长的列拼接在一起,需要用Series
Series
可以用unique()
方法对所有值进行去重处理。DataFrame不可以。- 添加列(不可以用
df.four
):df["four] = pd.Series(np.arange(10,14))
- 添加行
# 转置 df_line = pd.DataFrame(["twilight", "abc", "abcdefghijklmn", "a", "shflksahfkshadkfhasdkhfksh"]).T df_line.columns = df.columns # 统一columns pd.concat([df,df_line]) # 默认依然保存原来的index df = pd.concat([df,df_line],ignore_index=True) # 忽略原来的index,使index编程df的最大值+1
一些常见方法:
- max()
- argmax()
- min()
- agrmin()
- megian()
...
统计方法
合并
merge() & join()
默认是列方向的连接
merge(left,right,how="inner", on="name",left_on, right_on, left_index, right_index, sort=True, suffixes=('_a','_b'), copy=False)
left
参与合并的左侧DataFrameright
参与合并的右侧DataFramehow
连接方式:‘inner’(默认);还有,‘outer’、‘left’、‘right’on
用于连接的列名,必须同时存在于左右两个DataFrame对象中,如果未指定,则以left和right列名的交集作为连接键(最大公共子集)left_on
左侧DataFarme中用作连接键的列right_on
右侧DataFarme中用作连接键的列left_index
将左侧的行索引用作其连接键right_index
将右侧的行索引用作其连接键sort
根据连接键对合并后的数据进行排序,默认为True。有时在处理大数据集时,禁用该选项可获得更好的性能suffixes
字符串值元组,用于追加到重叠列名的末尾,默认为(‘_x’,‘_y’).例如,左右两个DataFrame对象都有‘data’,则结果中就会出现‘data_x’,‘data_y’copy
设置为False,可以在某些特殊情况下避免将数据复制到结果数据结构中。默认总是赋值
行连接,将某一列的所有的值,与另一个DataFrame的index进行比较,值相等时就合并。
df2 = pd.DataFrame({"id":[2,3,4], "name":["tim", "karl","kaven"], "height":[120, 130, 140]})
df3 = pd.DataFrame({"name":["karl", "kaven", "tomas"], "hair":["black", "blue", "red"]})
df3 = df3.set_index("name")
merge(df2, df3, how="left", left_on="name", right_index=True)
结果输出如下:
id name height
0 2 tim 120
1 3 karl 130
2 4 kaven 140
name hair
0 karl black
1 kaven blue
2 tomas red
df3_setindex
hair
name
karl black
kaven blue
tomas red
按行连接
id name height hair
0 2 tim 120 NaN
1 3 karl 130 black
2 4 kaven 140 blue
join() 参数列表和merge一样,不过
how="left"
默认表示左外连接.按行连接
concat()
pd.concat(objs, axis=0, join='outer', join_axes=None, ignore_index=False,copy=True)
objs
: dataFrame列表axis
: 0 表示按行拼接; 1 表示按列拼接join
: 默认是outer; 还可以取inner; inner就是保留没有NaN的行或者列ignore_index
: 默认是False,False表示保留那一行的index,True表示,将这里行的索引设置为最大index+1
grougby()
分组
group2 = df1.groupby(["name", 'age'])
- 分组结果不可以直接输出(
<pandas.core.groupby.generic.DataFrameGroupBy object at 0x0000095AF0F48CF8>
) - 可以用for循环迭代分组结果:
for key, value in grouped: print("key:", key) print("value:", (value)) #DataFrame类型
- 按照多个列分组时,key是tuple类型