Pandas常用方法

数据处理很多需要用到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("\ns2:\n", s2)

# 使用list创建
s3 = pd.Series([1,2,"10",4,5], index=['a',1,'c','d', 2.2], dtype=float)
print("\ns3:\n", s3)

# 使用字典创建
## 字典的建的顺序会被index改变, key变成了行,一维数组,只有行
s4 = pd.Series({'a':1, 'b':2, 'c':3}, index=['b', 'c', 'a', 'd'])
print("\ns4:", s4)

# 使用常量创建
s5 = pd.Series(10, index=[1,2,3,4,5])
print("\ns5:", 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的值

使用indexvalues可以访问索引和值,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)

数据可以采取各种形式,如:ndarrayseriesmaplistsdictconstant和另一个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.TDataFrame的转置,类似二维数组的转置

  • 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=0axis="index"), 对列排序(axis=1axis="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 参与合并的左侧DataFrame
  • right 参与合并的右侧DataFrame
  • how 连接方式:‘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类型
posted @ 2020-07-27 11:22  twilight0402  阅读(131)  评论(0编辑  收藏  举报