目录

数据合并

实现数据库表join功能

当我们有多张表的时候, 经常会遇到的一个问题就是, 如何把这些表关联起来, 我们可以想想我们在数据库的时候,

进场会遇到表连接的问题, 比如join, union等等, 其实这里等同于是在pandas里实现了这些

功能. 首先, 我们来看看这个join在pandas里是怎么实现的.

我们在pandas里主要通过merge来实现数据库的join工作.

  1. from pandas import Series, DataFrame
  2. import pandas as pd
  3. import numpy as np
  4. sep = "---------------------------------------------------------------------"
  1. data1 = {"data1": [1, 2, 3, 4, 5], "key":['a', 'b', 'c', 'd', 'e']}
  2. data2 = {"data2": [1, 2, 3,100], "key":['a', 'b', 'c', 'f']}
  3. frame1 = DataFrame(data1)
  4. frame2 = DataFrame(data2)
  5. print(frame1)
  6. print(sep)
  7. print(frame2)
  8. print(sep)
  9. print(pd.merge(frame1, frame2, on="key"))
  1. data1 key
  2. 0 1 a
  3. 1 2 b
  4. 2 3 c
  5. 3 4 d
  6. 4 5 e
  7. ---------------------------------------------------------------------
  8. data2 key
  9. 0 1 a
  10. 1 2 b
  11. 2 3 c
  12. 3 100 f
  13. ---------------------------------------------------------------------
  14. data1 key data2
  15. 0 1 a 1
  16. 1 2 b 2
  17. 2 3 c 3

注意, 我们默认是inner方式的连接, 对于数据库怎么做连接的, 以及连接的种类, 留作作业.

作业1: 熟悉数据库连接的方式.

  1. # 左外连
  2. print(pd.merge(frame1, frame2, on="key", how='left'))
  1. data1 key data2
  2. 0 1 a 1.0
  3. 1 2 b 2.0
  4. 2 3 c 3.0
  5. 3 4 d NaN
  6. 4 5 e NaN
  1. # 右外连
  2. print(pd.merge(frame1, frame2, on="key", how='right'))
  1. data1 key data2
  2. 0 1.0 a 1
  3. 1 2.0 b 2
  4. 2 3.0 c 3
  5. 3 NaN f 100
  1. # 外连接
  2. print(pd.merge(frame1, frame2, on="key", how='outer'))
  1. data1 key data2
  2. 0 1.0 a 1.0
  3. 1 2.0 b 2.0
  4. 2 3.0 c 3.0
  5. 3 4.0 d NaN
  6. 4 5.0 e NaN
  7. 5 NaN f 100.0

我们看到, 这和我们数据库的是一模一样, 我们主要到, on可以指定要关联的列名, 但是我们可能需要关联的列名不同, 这时候我们要分别指定.

  1. data1 = {"data1": [1, 2, 3, 4, 5], "key1":['a', 'b', 'c', 'd', 'e']}
  2. data2 = {"data2": [1, 2, 3,100], "key2":['a', 'b', 'c', 'f']}
  3. frame1 = DataFrame(data1)
  4. frame2 = DataFrame(data2)
  5. print(frame1)
  6. print(sep)
  7. print(frame2)
  1. data1 key1
  2. 0 1 a
  3. 1 2 b
  4. 2 3 c
  5. 3 4 d
  6. 4 5 e
  7. ---------------------------------------------------------------------
  8. data2 key2
  9. 0 1 a
  10. 1 2 b
  11. 2 3 c
  12. 3 100 f

如果我们要在把key1和key2关联起来, 我们可以怎么做呢? 在sql中, 我们可以用on (key1 = key2), 在pandas中, 我们可以这么做:

  1. print(pd.merge(frame1, frame2, how='inner', left_on='key1', right_on='key2').drop("key1", axis=1))
  1. data1 data2 key2
  2. 0 1 1 a
  3. 1 2 2 b
  4. 2 3 3 c

我们发现一个有趣的现象:

  1. print(pd.merge(frame1, frame2, how='outer', left_on='key1', right_on='key2'))
  1. data1 key1 data2 key2
  2. 0 1.0 a 1.0 a
  3. 1 2.0 b 2.0 b
  4. 2 3.0 c 3.0 c
  5. 3 4.0 d NaN NaN
  6. 4 5.0 e NaN NaN
  7. 5 NaN NaN 100.0 f

我们发现, 这个数据就不一样了, 因为我们是外连接,会保留所有的数据.

多个键做关联也是一样的, 只不过把on改成一个list.

作业2: 研究多个键关联.

下面我们来说一个有趣的东西, 我们来看:

  1. data1 = {"data": [1, 2, 3, 4, 5], "key":['a', 'b', 'c', 'd', 'e']}
  2. data2 = {"data": [1, 2, 3,100], "key":['a', 'b', 'c', 'f']}
  3. frame1 = DataFrame(data1)
  4. frame2 = DataFrame(data2)
  5. print(frame1)
  6. print(sep)
  7. print(frame2)
  8. print(sep)
  9. print(pd.merge(frame1, frame2, on='key'))
  1. data key
  2. 0 1 a
  3. 1 2 b
  4. 2 3 c
  5. 3 4 d
  6. 4 5 e
  7. ---------------------------------------------------------------------
  8. data key
  9. 0 1 a
  10. 1 2 b
  11. 2 3 c
  12. 3 100 f
  13. ---------------------------------------------------------------------
  14. data_x key data_y
  15. 0 1 a 1
  16. 1 2 b 2
  17. 2 3 c 3

我们发现对于列名重复的列, 会自动加上一个后缀, 左边+_x, 右边+_y, 注意这个后缀, 我们是可以自己定义的.

  1. print(pd.merge(frame1, frame2, on='key', suffixes=["-a", "-b"]))
  1. data-a key data-b
  2. 0 1 a 1
  3. 1 2 b 2
  4. 2 3 c 3

然后我们的问题来了, 如果我们要关联的列, 是索引怎么办 , 这个问题有点意思, 但是merge这个函数已经为大家都设计好了,

我们可以这样搞:

  1. data1 = {"data": [1, 2, 3, 4, 5], "key":['a', 'b', 'c', 'd', 'e']}
  2. data2 = {"data": [1, 2, 3,100], "key":['a', 'b', 'c', 'f']}
  3. frame1 = DataFrame(data1, index=['a', 'b', 'c', 'd', 'e'])
  4. frame2 = DataFrame(data2, index = ['a', 'b', 'c', 'f'])
  5. print(frame1)
  6. print(sep)
  7. print(frame2)
  8. print(sep)
  9. print(pd.merge(frame1, frame2, left_index=True, right_index=True))
  10. print(sep)
  11. frame2 = DataFrame(data2, index = ['1', '2', '3', '4'])
  12. print(frame2)
  13. print(sep)
  14. print(pd.merge(frame1, frame2, left_index=True, right_on='key', how='left'))
  1. data key
  2. a 1 a
  3. b 2 b
  4. c 3 c
  5. d 4 d
  6. e 5 e
  7. ---------------------------------------------------------------------
  8. data key
  9. a 1 a
  10. b 2 b
  11. c 3 c
  12. f 100 f
  13. ---------------------------------------------------------------------
  14. data_x key_x data_y key_y
  15. a 1 a 1 a
  16. b 2 b 2 b
  17. c 3 c 3 c
  18. ---------------------------------------------------------------------
  19. data key
  20. 1 1 a
  21. 2 2 b
  22. 3 3 c
  23. 4 100 f
  24. ---------------------------------------------------------------------
  25. key data_x key_x data_y key_y
  26. 1 a 1 a 1.0 a
  27. 2 b 2 b 2.0 b
  28. 3 c 3 c 3.0 c
  29. 4 d 4 d NaN NaN
  30. 4 e 5 e NaN NaN

最后一个例子是把frame1的index和frame2的key连接了起来, 这里我们发现, frame1的索引因为被merge掉了, frame2的索引保留了下来, 同时frame1的key被保留了下来.

我们还有一个函数是join, 他也是实现了按索引关联.

  1. frame1

.dataframe thead tr:only-child th {
text-align: right;
}

  1. .dataframe thead th {
  2. text-align: left;
  3. }
  4. .dataframe tbody tr th {
  5. vertical-align: top;
  6. }
data key
a 1 a
b 2 b
c 3 c
d 4 d
e 5 e
  1. frame2

.dataframe thead tr:only-child th {
text-align: right;
}

  1. .dataframe thead th {
  2. text-align: left;
  3. }
  4. .dataframe tbody tr th {
  5. vertical-align: top;
  6. }
data key
1 1 a
2 2 b
3 3 c
4 100 f
  1. frame1.join(frame2, lsuffix="_x", rsuffix="_y")

.dataframe thead tr:only-child th {
text-align: right;
}

  1. .dataframe thead th {
  2. text-align: left;
  3. }
  4. .dataframe tbody tr th {
  5. vertical-align: top;
  6. }
data_x key_x data_y key_y
a 1 a NaN NaN
b 2 b NaN NaN
c 3 c NaN NaN
d 4 d NaN NaN
e 5 e NaN NaN

我们发现调用者的索引被保留了下来.

  1. # 参数的索引和调用者的列关联在一起
  2. frame2.join(frame1, lsuffix="_x", rsuffix="_y", on="key")

.dataframe thead tr:only-child th {
text-align: right;
}

  1. .dataframe thead th {
  2. text-align: left;
  3. }
  4. .dataframe tbody tr th {
  5. vertical-align: top;
  6. }
data_x key_x data_y key_y
1 1 a 1.0 a
2 2 b 2.0 b
3 3 c 3.0 c
4 100 f NaN NaN

这里设置了on参数, 因此是调用者的列参数的索引关联, 最后保留了调用者的索引.

实现union功能

上面介绍的都是列关联的,也就是join, 之后我们会看怎么做union. 所谓union就是在纵向上面做连接, 我们可以看到, 这种方式, 可以两张列相同的表拼接起来.

  1. # Series的连接
  2. a = Series([1, 2, 3], index=['a', 'b', 'c'])
  3. b = Series([3, 4], index=['d' , 'e'])
  4. c = Series([6, 7], index=['e', 'f'])
  5. pd.concat([a, b, c])
  1. a 1
  2. b 2
  3. c 3
  4. d 3
  5. e 4
  6. e 6
  7. f 7
  8. dtype: int64

我们看到, 这样就把这3个Series拼接起来了, 默认是在axis=0上连接的, 但是我们也可以在axis=1上连接, 我们来看看结果怎么样.

  1. pd.concat([a, b, c], axis=1)

.dataframe thead tr:only-child th {
text-align: right;
}

  1. .dataframe thead th {
  2. text-align: left;
  3. }
  4. .dataframe tbody tr th {
  5. vertical-align: top;
  6. }
0 1 2
a 1.0 NaN NaN
b 2.0 NaN NaN
c 3.0 NaN NaN
d NaN 3.0 NaN
e NaN 4.0 6.0
f NaN NaN 7.0

我们看到, 这个相当于是这3个Series按索引做外连接. 如果我们要做内连接, 怎么办呢?

  1. pd.concat([b, c], axis=1, join='inner')

.dataframe thead tr:only-child th {
text-align: right;
}

  1. .dataframe thead th {
  2. text-align: left;
  3. }
  4. .dataframe tbody tr th {
  5. vertical-align: top;
  6. }
0 1
e 4 6

如果要区分从原来哪些地方合并而来的, 我们可以指定keys:

  1. pd.concat([a, b, c], keys=['one', 'two', 'three'])
  1. one a 1
  2. b 2
  3. c 3
  4. two d 3
  5. e 4
  6. threee e 6
  7. f 7
  8. dtype: int64
  1. pd.concat([a, b, c], axis=1, keys=['one', 'two', 'three'])

.dataframe thead tr:only-child th {
text-align: right;
}

  1. .dataframe thead th {
  2. text-align: left;
  3. }
  4. .dataframe tbody tr th {
  5. vertical-align: top;
  6. }
one two three
a 1.0 NaN NaN
b 2.0 NaN NaN
c 3.0 NaN NaN
d NaN 3.0 NaN
e NaN 4.0 6.0
f NaN NaN 7.0

我们发现, 我们的keys在axis=1连接的时候, 变成了列头.

我们下面来看看如果是两个DataFrame, 会怎么样.

  1. f1 = DataFrame(np.arange(6).reshape(3, 2), index=['a', 'b', 'c'], columns=['one', 'two'])
  2. f2 = DataFrame(np.arange(4).reshape(2, 2), index=['c', 'd'], columns=['three', 'four'])
  3. print(f1)
  4. print(sep)
  5. print(f2)
  1. one two
  2. a 0 1
  3. b 2 3
  4. c 4 5
  5. ---------------------------------------------------------------------
  6. three four
  7. c 0 1
  8. d 2 3
  1. pd.concat([f1, f2])

.dataframe thead tr:only-child th {
text-align: right;
}

  1. .dataframe thead th {
  2. text-align: left;
  3. }
  4. .dataframe tbody tr th {
  5. vertical-align: top;
  6. }
four one three two
a NaN 0.0 NaN 1.0
b NaN 2.0 NaN 3.0
c NaN 4.0 NaN 5.0
c 1.0 NaN 0.0 NaN
d 3.0 NaN 2.0 NaN

这就是我们要的union效果, 我们也可以区分出来源

  1. pd.concat([f1, f2], keys=[1, 2])

.dataframe thead tr:only-child th {
text-align: right;
}

  1. .dataframe thead th {
  2. text-align: left;
  3. }
  4. .dataframe tbody tr th {
  5. vertical-align: top;
  6. }
four one three two
1 a NaN 0.0 NaN 1.0
b NaN 2.0 NaN 3.0
c NaN 4.0 NaN 5.0
2 c 1.0 NaN 0.0 NaN
d 3.0 NaN 2.0 NaN
  1. pd.concat([f1, f2], keys=[1, 2], axis=1)

.dataframe thead tr:only-child th {
text-align: right;
}

  1. .dataframe thead th {
  2. text-align: left;
  3. }
  4. .dataframe tbody tr th {
  5. vertical-align: top;
  6. }
1 2
one two three four
a 0.0 1.0 NaN NaN
b 2.0 3.0 NaN NaN
c 4.0 5.0 0.0 1.0
d NaN NaN 2.0 3.0

如果我们不想要原来的索引, 而想要重新索引, 我们可以这样来:

  1. pd.concat([f1, f2], ignore_index=True)

.dataframe thead tr:only-child th {
text-align: right;
}

  1. .dataframe thead th {
  2. text-align: left;
  3. }
  4. .dataframe tbody tr th {
  5. vertical-align: top;
  6. }
four one three two
0 NaN 0.0 NaN 1.0
1 NaN 2.0 NaN 3.0
2 NaN 4.0 NaN 5.0
3 1.0 NaN 0.0 NaN
4 3.0 NaN 2.0 NaN

总结起来, concat默认就是union的功能, 但是我们可以通过设置axis=1达到按索引关联的功能.

数据转换

轴旋转

这里我们要来聊聊轴旋转的课题, 其中主要用到两个函数:

  • stack 将列旋转为行
  • unstack 将行旋转为列
  1. data = DataFrame(np.arange(6).reshape(2, 3), columns=pd.Index(['a', 'b', 'c'], name="column"), index=pd.Index(["one", "two"], name="index"))
  2. print(data)
  1. column a b c
  2. index
  3. one 0 1 2
  4. two 3 4 5

我们来stack一下, 看看会有什么结果:

  1. print(data.stack())
  2. print(sep)
  3. print(data['a']['one'])
  4. print(data.loc['one']['a'])
  5. print(sep)
  6. print(data.stack()['one', 'a'])
  1. index column
  2. one a 0
  3. b 1
  4. c 2
  5. two a 3
  6. b 4
  7. c 5
  8. dtype: int32
  9. ---------------------------------------------------------------------
  10. 0
  11. 0
  12. ---------------------------------------------------------------------
  13. 0

我们看到, 我们把每一行都变成了一列, 然后堆了起来, 变成了一个Series.

  1. print(data.stack().unstack())
  1. column a b c
  2. index
  3. one 0 1 2
  4. two 3 4 5

我们来看看, 如果我们把stack后的two, c项给删了, 会怎么样呢?

  1. a = data.stack()
  2. del a['two', 'c']
  3. print(a.unstack())
  1. column a b c
  2. index
  3. one 0.0 1.0 2.0
  4. two 3.0 4.0 NaN

在unstack的时候, 会自动补充NaN值来对齐, 而在stack的时候, 会删除这些NaN值.

  1. a.unstack().stack()
  1. index column
  2. one a 0.0
  3. b 1.0
  4. c 2.0
  5. two a 3.0
  6. b 4.0
  7. dtype: float64

我们发现, 我们在做stack还是unstack的时候, 都是从最内测的轴开始的

  1. b = a.unstack().stack()
  2. print(b)
  3. print(sep)
  4. print(b.unstack())
  1. index column
  2. one a 0.0
  3. b 1.0
  4. c 2.0
  5. two a 3.0
  6. b 4.0
  7. dtype: float64
  8. ---------------------------------------------------------------------
  9. column a b c
  10. index
  11. one 0.0 1.0 2.0
  12. two 3.0 4.0 NaN

确实是内侧的column转到了列上面去. 如果我们要转外侧的索引呢, 我们可以指定数字或者列名.

  1. print(b.unstack(0))
  2. print(b.unstack("index"))
  1. index one two
  2. column
  3. a 0.0 3.0
  4. b 1.0 4.0
  5. c 2.0 NaN
  6. index one two
  7. column
  8. a 0.0 3.0
  9. b 1.0 4.0
  10. c 2.0 NaN

.dataframe thead tr:only-child th {
text-align: right;
}

  1. .dataframe thead th {
  2. text-align: left;
  3. }
  4. .dataframe tbody tr th {
  5. vertical-align: top;
  6. }
index one two
count 3.0 2.000000
mean 1.0 3.500000
std 1.0 0.707107
min 0.0 3.000000
25% 0.5 3.250000
50% 1.0 3.500000
75% 1.5 3.750000
max 2.0 4.000000

这样, 行和列就互换了.

强调一下:

stack: 把行变成列. 我们可以这么理解, 把行堆到了列上.

unstack: 把列变成行, 把列反堆到了行上.

数据转换

去重

去除重复数据, 我们这里主要讲讲怎么能够把重复的数据进行去除

  1. data = DataFrame({'one':[1, 1, 2, 2, 3],'two':[1, 1, 2, 2, 3]})
  2. print(data)
  1. one two
  2. 0 1 1
  3. 1 1 1
  4. 2 2 2
  5. 3 2 2
  6. 4 3 3
  1. print(data.drop_duplicates())
  1. one two
  2. 0 1 1
  3. 2 2 2
  4. 4 3 3
  1. data = DataFrame({'one':[1, 1, 2, 2, 3],'two':[1, 1, 2, 2, 3], 'three':[5, 6, 7, 8, 9]})
  2. print(data)
  1. one three two
  2. 0 1 5 1
  3. 1 1 6 1
  4. 2 2 7 2
  5. 3 2 8 2
  6. 4 3 9 3

.dataframe thead tr:only-child th {
text-align: right;
}

  1. .dataframe thead th {
  2. text-align: left;
  3. }
  4. .dataframe tbody tr th {
  5. vertical-align: top;
  6. }
one three two
count 5.00000 5.000000 5.00000
mean 1.80000 7.000000 1.80000
std 0.83666 1.581139 0.83666
min 1.00000 5.000000 1.00000
25% 1.00000 6.000000 1.00000
50% 2.00000 7.000000 2.00000
75% 2.00000 8.000000 2.00000
max 3.00000 9.000000 3.00000

我们可以按照某一列来进行去重

  1. print(data.drop_duplicates(['one']))
  1. one three two
  2. 0 1 5 1
  3. 2 2 7 2
  4. 4 3 9 3

去重默认是按照保留最先出现的一个, 我们也可以保留最后出现的一个.

**作业3: 去重, 保留最后出现的一个. **

对某一列运用函数

我们之前提到过, 对于一整列或者一整行, 可以用apply函数, 对于每个元素, 可以用applymap函数, 如果我们要对某一列的

每个元素进行运算, 我们可以用map函数.

  1. data = DataFrame({'one':['a', 'b', 'c'],'two':['e', 'd', 'f']})
  2. print(data)
  3. print(sep)
  4. data['one'] = data['one'].map(str.upper)
  5. print(data)
  1. one two
  2. 0 a e
  3. 1 b d
  4. 2 c f
  5. ---------------------------------------------------------------------
  6. one two
  7. 0 A e
  8. 1 B d
  9. 2 C f

如果我们只想把a变成大写呢, 我们可以用传入一个map的方法.

  1. data = DataFrame({'one':['a', 'b', 'c'],'two':['e', 'd', 'f']})
  2. print(data)
  3. print(sep)
  4. data['one'] = data['one'].map({'a':'A', 'b':'b', 'c':'c'})
  5. print(data)
  1. one two
  2. 0 a e
  3. 1 b d
  4. 2 c f
  5. ---------------------------------------------------------------------
  6. one two
  7. 0 A e
  8. 1 b d
  9. 2 c f

在最后一个例子中, 我们发现要提供b和c的值, 太麻烦了, 可以用replace函数:


  1. data['one'] = data['one'].replace('A', 'a')
  2. print(data)
  1. one two
  2. 0 a e
  3. 1 b d
  4. 2 c f
重命名行和列名

这里我们来谈谈怎么重命名行或者列的名字. 我们可以用rename函数来完成, 比如我们希望把列名的首字母大写等等, 这个就留作作业.

作业4: 重命名行名和列名, 把首字母大写.

离散化

这里会讲一个很有用的技能, 就是离散化, 这个在我们后面处理特征的时候是非常有用的. 离散化主要是用到cut和qcut函数.

  1. a = np.arange(20)
  2. print(a)
  1. [ 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19]
  1. pd.cut(a, 4) # 这个4将最大值和最小值间分成4等分
  1. [(-0.019, 4.75], (-0.019, 4.75], (-0.019, 4.75], (-0.019, 4.75], (-0.019, 4.75], ..., (14.25, 19.0], (14.25, 19.0], (14.25, 19.0], (14.25, 19.0], (14.25, 19.0]]
  2. Length: 20
  3. Categories (4, interval[float64]): [(-0.019, 4.75] < (4.75, 9.5] < (9.5, 14.25] < (14.25, 19.0]]
  1. pd.qcut(a, 4) # 这个4按照个数分成四等分
  1. [(-0.001, 4.75], (-0.001, 4.75], (-0.001, 4.75], (-0.001, 4.75], (-0.001, 4.75], ..., (14.25, 19.0], (14.25, 19.0], (14.25, 19.0], (14.25, 19.0], (14.25, 19.0]]
  2. Length: 20
  3. Categories (4, interval[float64]): [(-0.001, 4.75] < (4.75, 9.5] < (9.5, 14.25] < (14.25, 19.0]]
  1. pd.qcut(a, 4).codes #输出codes
  1. array([0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3], dtype=int8)

我们也可以按照我们指定的分割点来, 这个留作作业.

**作业5: 按照自己定义的分割点来分割 **

过滤数据

这个小节的功能类似于select中的where语句, 但是要灵活的多, 我们先来看看怎么选出绝对值大于2的行.

  1. data = DataFrame(np.random.randn(10, 10))
  2. print(data)
  1. 0 1 2 3 4 5 6 \
  2. 0 -0.064111 -1.237009 0.040219 -0.300265 -0.195558 0.018277 -0.484843
  3. 1 -0.497673 -0.010135 -1.482219 -0.239210 -0.789893 0.593664 0.345015
  4. 2 -1.818869 0.613175 -0.165610 0.649670 -1.364698 0.444785 -0.146202
  5. 3 -0.274151 0.718986 0.321961 -0.416124 -0.275706 -0.738405 -0.260420
  6. 4 1.980359 -0.429317 -0.964024 -1.474141 0.339342 -0.932012 -0.116387
  7. 5 -0.518374 -0.224879 -1.517607 -0.079120 0.728408 1.218297 1.191882
  8. 6 -0.508048 2.010942 1.338983 2.026203 -0.794110 -1.370830 1.364660
  9. 7 0.855870 -0.804471 0.939610 0.796154 0.467878 0.362091 -1.892815
  10. 8 1.059561 0.223369 1.098954 1.583732 0.865225 -0.597980 -1.853170
  11. 9 -0.434388 0.475098 -0.103491 -0.735113 0.823425 -0.905158 0.145539
  12. 7 8 9
  13. 0 -1.370281 0.112070 -0.387124
  14. 1 0.049215 0.578946 0.462688
  15. 2 0.085562 2.906838 -1.059603
  16. 3 -0.327103 0.504234 0.192760
  17. 4 0.826963 1.188256 0.590085
  18. 5 -0.061007 1.955653 -0.984727
  19. 6 -0.471252 1.067497 0.550022
  20. 7 -0.503244 -0.288634 1.121110
  21. 8 -0.650933 0.138730 -0.389139
  22. 9 -2.078052 0.158038 -0.109184
  1. print(data[np.abs(data) > 2])
  1. 0 1 2 3 4 5 6 7 8 9
  2. 0 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
  3. 1 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
  4. 2 NaN NaN NaN NaN NaN NaN NaN NaN 2.906838 NaN
  5. 3 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
  6. 4 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
  7. 5 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
  8. 6 NaN 2.010942 NaN 2.026203 NaN NaN NaN NaN NaN NaN
  9. 7 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
  10. 8 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
  11. 9 NaN NaN NaN NaN NaN NaN NaN -2.078052 NaN NaN

完了, 居然是这幅德行

  1. np.abs(data) > 2

.dataframe thead tr:only-child th {
text-align: right;
}

  1. .dataframe thead th {
  2. text-align: left;
  3. }
  4. .dataframe tbody tr th {
  5. vertical-align: top;
  6. }
0 1 2 3 4 5 6 7 8 9
0 False False False False False False False False False False
1 False False False False False False False False False False
2 False False False False False False False False True False
3 False False False False False False False False False False
4 False False False False False False False False False False
5 False False False False False False False False False False
6 False True False True False False False False False False
7 False False False False False False False False False False
8 False False False False False False False False False False
9 False False False False False False False True False False

我们发现, false的这些地方, 都被设为NaN, 我们不想要这些false的数据, 我们只需要存在一个大于2的行, 我们看看apply函数行不行呢?

  1. data[(np.abs(data) > 2).apply(lambda x: x.name if x.sum() > 0 else None, axis=1).notnull()]

.dataframe thead tr:only-child th {
text-align: right;
}

  1. .dataframe thead th {
  2. text-align: left;
  3. }
  4. .dataframe tbody tr th {
  5. vertical-align: top;
  6. }
0 1 2 3 4 5 6 7 8 9
2 -1.818869 0.613175 -0.165610 0.649670 -1.364698 0.444785 -0.146202 0.085562 2.906838 -1.059603
6 -0.508048 2.010942 1.338983 2.026203 -0.794110 -1.370830 1.364660 -0.471252 1.067497 0.550022
9 -0.434388 0.475098 -0.103491 -0.735113 0.823425 -0.905158 0.145539 -2.078052 0.158038 -0.109184

这样看上去实在是太复杂了, 其实可以简化

  1. (np.abs(data) > 2).any(1)
  1. 0 False
  2. 1 False
  3. 2 True
  4. 3 False
  5. 4 False
  6. 5 False
  7. 6 True
  8. 7 False
  9. 8 False
  10. 9 True
  11. dtype: bool
  1. data[(np.abs(data) > 2).any(1)] # 有一个真就是真

.dataframe thead tr:only-child th {
text-align: right;
}

  1. .dataframe thead th {
  2. text-align: left;
  3. }
  4. .dataframe tbody tr th {
  5. vertical-align: top;
  6. }
0 1 2 3 4 5 6 7 8 9
2 -1.818869 0.613175 -0.165610 0.649670 -1.364698 0.444785 -0.146202 0.085562 2.906838 -1.059603
6 -0.508048 2.010942 1.338983 2.026203 -0.794110 -1.370830 1.364660 -0.471252 1.067497 0.550022
9 -0.434388 0.475098 -0.103491 -0.735113 0.823425 -0.905158 0.145539 -2.078052 0.158038 -0.109184

这里这个any(1)相当于是apply(lambda x: x.name if x.sum() > 0 else None, axis=1).notnull()

转换为onehot表示

下面我们来提一个东西, 就是怎么将数据转换为onehot的表示.

  1. data = DataFrame({'one': np.arange(20), 'two': np.arange(20)})
  2. data.join(pd.get_dummies(pd.cut(data['one'], 4).values.codes, prefix="one_"))

.dataframe thead tr:only-child th {
text-align: right;
}

  1. .dataframe thead th {
  2. text-align: left;
  3. }
  4. .dataframe tbody tr th {
  5. vertical-align: top;
  6. }
one two one__0 one__1 one__2 one__3
0 0 0 1 0 0 0
1 1 1 1 0 0 0
2 2 2 1 0 0 0
3 3 3 1 0 0 0
4 4 4 1 0 0 0
5 5 5 0 1 0 0
6 6 6 0 1 0 0
7 7 7 0 1 0 0
8 8 8 0 1 0 0
9 9 9 0 1 0 0
10 10 10 0 0 1 0
11 11 11 0 0 1 0
12 12 12 0 0 1 0
13 13 13 0 0 1 0
14 14 14 0 0 1 0
15 15 15 0 0 0 1
16 16 16 0 0 0 1
17 17 17 0 0 0 1
18 18 18 0 0 0 1
19 19 19 0 0 0 1

是不是超级简单.

字符串操作

我们来看看字符串的操作, 其实主要还是正则表达式, 我们来看一个例子:

  1. data = DataFrame({'a':["xiaoming@sina.com", "xiaozhang@gmail.com", "xiaohong@qq.com"], 'b':[1, 2, 3]})
  2. print(data)
  1. a b
  2. 0 xiaoming@sina.com 1
  3. 1 xiaozhang@gmail.com 2
  4. 2 xiaohong@qq.com 3
  1. import re
  2. pattern = r'([A-Z]+)@([A-Z]+)\.([A-Z]{2,4})'
  3. data['a'].str.findall(pattern, flags=re.IGNORECASE).str[0].str[1]
  1. 0 sina
  2. 1 gmail
  3. 2 qq
  4. Name: a, dtype: object

我们看到, 我们可以用python的正则表达式来处理字符串问题.

作业6: 熟悉python正则表达式. http://www.runoob.com/python3/python3-reg-expressions.html

数据分析之pandas教程------数据处理的更多相关文章

  1. 数据分析之pandas教程-----概念篇

    目录 1  pandas基本概念 1.1  pandas数据结构剖析 1.1.1  Series 1.1.2  DataFrame 1.1.3  索引 1.1.4  pandas基本操作 1.1.4. ...

  2. 利用Python进行数据分析(7) pandas基础: Series和DataFrame的简单介绍

    一.pandas 是什么 pandas 是基于 NumPy 的一个 Python 数据分析包,主要目的是为了数据分析.它提供了大量高级的数据结构和对数据处理的方法. pandas 有两个主要的数据结构 ...

  3. Python运用于数据分析的简单教程

    Python运用于数据分析的简单教程 这篇文章主要介绍了Python运用于数据分析的简单教程,主要介绍了如何运用Python来进行数据导入.变化.统计和假设检验等基本的数据分析,需要的朋友可以参考下 ...

  4. 利用Python进行数据分析(12) pandas基础: 数据合并

    pandas 提供了三种主要方法可以对数据进行合并: pandas.merge()方法:数据库风格的合并: pandas.concat()方法:轴向连接,即沿着一条轴将多个对象堆叠到一起: 实例方法c ...

  5. 利用Python进行数据分析(9) pandas基础: 汇总统计和计算

    pandas 对象拥有一些常用的数学和统计方法.   例如,sum() 方法,进行列小计:   sum() 方法传入 axis=1 指定为横向汇总,即行小计:   idxmax() 获取最大值对应的索 ...

  6. 利用Python进行数据分析(8) pandas基础: Series和DataFrame的基本操作

    一.reindex() 方法:重新索引 针对 Series   重新索引指的是根据index参数重新进行排序. 如果传入的索引值在数据里不存在,则不会报错,而是添加缺失值的新行. 不想用缺失值,可以用 ...

  7. Python爬虫与数据分析之进阶教程:文件操作、lambda表达式、递归、yield生成器

    专栏目录: Python爬虫与数据分析之python教学视频.python源码分享,python Python爬虫与数据分析之基础教程:Python的语法.字典.元组.列表 Python爬虫与数据分析 ...

  8. Xamarin Essentials教程数据处理传输数据

    Xamarin Essentials教程数据处理传输数据 在移动应用程序中,除了常规的数据处理,还涉及数据存储.数据传输.版本数据多个方面.Xamarin.Essentials组件提供了多个数据处理相 ...

  9. Python数据分析库pandas基本操作

    Python数据分析库pandas基本操作2017年02月20日 17:09:06 birdlove1987 阅读数:22631 标签: python 数据分析 pandas 更多 个人分类: Pyt ...

随机推荐

  1. C#面试常见题目

    1.CTS.CLS.CLR分别作何解释 CTS:Common Type System 通用系统类型.Int32.Int16→int.String→string.Boolean→bool CLS:Com ...

  2. sublime text3怎么批量查找替换文件夹中的字符

    在编写代码的时候,往往有些代码是重复的,但是如果要改一处代码,其他的地方也要改.那么怎么批量修改呢?下面小编就以sublime text3为例来讲解一下sublime text3怎么批量查找替换文件夹 ...

  3. Kafka 使用Java实现数据的生产和消费demo

    前言 在上一篇中讲述如何搭建kafka集群,本篇则讲述如何简单的使用 kafka .不过在使用kafka的时候,还是应该简单的了解下kafka. Kafka的介绍 Kafka是一种高吞吐量的分布式发布 ...

  4. 【开发技术】视频URL采集

    http://www.joyplus.tv/joypluscms   志精

  5. IDEA、Matlab 注释

    IDEA ctrl+/ 多行代码分行注释,再按一次取消 ctrl+shift+/ 多行代码注释在一个块里,只在开头和结尾有注释符号 Matlab 注释:Ctrl+/ Ctrl+R 取消注释:Ctrl+ ...

  6. linux 3.10的kdump配置的小坑

    之前在2.6系列linux内核中,当发现某个模块不要在保留内核中加载的时候,可以通过blacklist参数将其在/etc/kdump.conf中屏蔽 blacklist <list of ker ...

  7. (2-3)Eureka详解

    基础架构 服务注册中心 服务提供者 服务消费者 服务治理 服务提供者 服务注册.在服务注册时,需要确认一下eureka.client.registerwith-eurek=ture参数是否正确,默认是 ...

  8. node.js核心模块

    全局对象 global 是全局变量的宿主 全局变量 在最外层定义的 全局对象的属性 隐士定义的变量(未定义直接赋值的变量) 当定义一个全局变量时 这个变量同时也会成为全局对象的属性 反之亦然 注意: ...

  9. Django_上传图片和模版获取图片

    需求: 在Django中,上传图片,存入数据库中的文件的路径,而不是图片本身,也就是说,图片等数据静态文件都可以放到第三方服务器上,我想在把图片保存到Django本地项目中,并可以通过Django自带 ...

  10. sqlserver2008客户端设置主键自增

    是标识改为是