这篇文章收集了网友们使用pandas进行数据分析时经常遇到的问题, 这些问题也可以检验你使用pandas的熟练程度, 所以他们更像是一个学习教材, 掌握这些技能, 可以使你数据数据分析的工作事半功倍。
下面是第三部分:
检查dataframe是否有缺失值1
2
3
4
5
6
7
8
9
10
11import pandas as pd
import numpy as np
df = pd.DataFrame({
'a':[1.2,2,3,4],
'b':list('abcd')
})
print('缺失:', df.isnull().values.any())
df.iat[0,0] = np.nan
print('缺失:', df.isnull().values.any())
输出(stream):
缺失: False
缺失: True
统计dataframe中每列缺失值的数量1df.apply(lambda x: x.isnull().sum())
输出(plain):
a 1
b 0
dtype: int64
dataframe用每列的平均值取代缺失值1
2df = pd.read_csv('https://raw.githubusercontent.com/selva86/datasets/master/Cars93_miss.csv')
df[['Min.Price', 'Max.Price']].head()
输出(html):
Min.Price
Max.Price
0
12.9
18.8
1
29.2
38.7
2
25.9
32.3
3
NaN
44.6
4
NaN
NaN
1
2# 仅使用['Min.Price', 'Max.Price']这两列演示
df[['Min.Price', 'Max.Price']].apply(lambda x: x.fillna(x.mean())).head()
输出(html):
Min.Price
Max.Price
0
12.900000
18.800000
1
29.200000
38.700000
2
25.900000
32.300000
3
17.118605
44.600000
4
17.118605
21.459091
从dataframe中获取某一列, 并返回一个dataframe1
2# 只要传入一个list作为切片
df[['Manufacturer']].head()
输出(html):
Manufacturer
0
Acura
1
NaN
2
Audi
3
Audi
4
BMW
dataframe如何改变列的顺序1
2df = pd.DataFrame(np.arange(20).reshape(-1, 5), columns=list('abcde'))
df.head()
输出(html):
a
b
c
d
e
0
0
1
2
3
4
1
5
6
7
8
9
2
10
11
12
13
14
3
15
16
17
18
19
1df[list('cbdae')]
输出(html):
c
b
d
a
e
0
2
1
3
0
4
1
7
6
8
5
9
2
12
11
13
10
14
3
17
16
18
15
19
设置dataframe输出的行数和列数1
2# 设置之前
df
输出(html):
a
b
c
d
e
0
0
1
2
3
4
1
5
6
7
8
9
2
10
11
12
13
14
3
15
16
17
18
19
1
2
3
4pd.set_option('display.max_columns', 4)
pd.set_option('display.max_rows', 4)
# 设置之后
df
输出(html):
a
b
...
d
e
0
0
1
...
3
4
1
5
6
...
8
9
2
10
11
...
13
14
3
15
16
...
18
19
4 rows × 5 columns
1
2pd.set_option('display.max_columns', 10)
pd.set_option('display.max_rows', 10)
设置dataframe输出时不使用科学记数法1pd.DataFrame(np.random.random(4)**10, columns=['random'])
输出(html):
random
0
4.285027e-07
1
1.580650e-05
2
2.049461e-01
3
6.873938e-06
1
2pd.set_option('display.float_format', lambda x: '%.4f' % x)
pd.DataFrame(np.random.random(4)**10, columns=['random'])
输出(html):
random
0
0.0000
1
0.9207
2
0.0209
3
0.0000
1
2
3# 恢复默认值
pd.set_option('display.float_format', None)
pd.DataFrame(np.random.random(4)**10, columns=['random'])
输出(html):
random
0
0.004970
1
0.018763
2
0.000058
3
0.252180
设置dataframe输出百分比数据1
2df = pd.DataFrame(np.random.random(4), columns=['random'])
df
输出(html):
random
0
0.343280
1
0.700357
2
0.885307
3
0.932272
1df.style.format({'random':'{0:.2%}'.format})
输出(html):
random
0
34.33%
1
70.04%
2
88.53%
3
93.23%
知识点:
使用百分号可以自动将数据转换为百分比格式:
'{0:.2%}'.format(0.555555)
使用多个列创建唯一索引(index)1
2
3df = pd.read_csv(
'https://raw.githubusercontent.com/selva86/datasets/master/Cars93_miss.csv',
usecols=[0,1,2,3,5])
1
2
3df[['Manufacturer', 'Model', 'Type']] = df[['Manufacturer', 'Model', 'Type']].fillna('missing')
df.index = df.Manufacturer + '_' + df.Model + '_' + df.Type
print(df.index.is_unique)
输出(stream):
True
获取第n大的数所在行1
2
3
4df = pd.DataFrame(
np.random.randint(1, 30, 30).reshape(10,-1),
columns=list('abc'))
df['a']
输出(plain):
0 21
1 17
2 19
3 3
4 2
5 3
6 10
7 5
8 25
9 12
Name: a, dtype: int32
1
2# 使用行号排序
df['a'].argsort()
输出(plain):
0 4
1 3
2 5
3 7
4 6
5 9
6 1
7 2
8 0
9 8
Name: a, dtype: int64
1
2
3# 可以这样看到原始数据的排序
df['a'][df['a'].argsort()]
输出(plain):
4 2
3 3
5 3
7 5
6 10
9 12
1 17
2 19
0 21
8 25
Name: a, dtype: int32
1
2n = 5
df['a'].argsort()[::-1][n]
输出(plain):
3
dataframe获取行之和大于100的数据, 并返回最后的两行1
2
3
4df = pd.DataFrame(np.random.randint(10, 40, 60).reshape(-1, 4))
rowsums = df.apply(np.sum, axis=1)
last_two_rows = df.iloc[np.where(rowsums > 100)[0][-2:], :]
last_two_rows
输出(html):
0
1
2
3
13
39
31
35
15
14
30
22
25
31
如何从系列或数据框列中查找和限制异常值
用相应的5%分位数和95%分位数值替换低于5%分位数和大于95%分位数的所有值
1
2
3
4
5
6
7
8
9
10
11
12# Input
ser = pd.Series(np.logspace(-2, 2, 30))
# Solution
def cap_outliers(ser, low_perc, high_perc):
low, high = ser.quantile([low_perc, high_perc])
print(low_perc, '%ile: ', low, '|', high_perc, '%ile: ', high)
ser[ser < low] = low
ser[ser > high] = high
return(ser)
capped_ser = cap_outliers(ser, .05, .95)
输出(stream):
0.05 %ile: 0.016049294076965887 | 0.95 %ile: 63.876672220183934
如何在删除负值后将dataframe重新整形为最大可能的正方形
将df重塑为最大可能的正方形,并删除负值。如果需要,删除最小值。结果中正数的顺序应保持与原始顺序相同。
1
2df = pd.DataFrame(np.random.randint(-20, 50, 100).reshape(10,-1))
print(df)
输出(stream):
0 1 2 3 4 5 6 7 8 9
0 12 -6 -15 14 33 -9 -14 46 7 6
1 23 -5 13 22 -10 35 -8 8 -20 34
2 19 49 18 -1 5 22 38 -5 27 34
3 -12 47 21 9 45 18 3 -10 27 42
4 48 32 41 -14 5 40 33 -3 10 11
5 17 -2 13 47 28 5 24 26 -7 10
6 49 21 14 -16 12 -17 3 43 8 -10
7 17 -19 -14 2 -8 -10 1 25 -9 48
8 25 46 -7 36 -13 18 42 31 49 37
9 2 25 47 28 9 49 10 44 -15 12
1
2
3
4
5# 步骤1:删除负数
arr = df[df > 0].values.flatten()
arr_qualified = arr[~np.isnan(arr)]
arr_qualified
输出(plain):
array([12., 14., 33., 46., 7., 6., 23., 13., 22., 35., 8., 34., 19.,
49., 18., 5., 22., 38., 27., 34., 47., 21., 9., 45., 18., 3.,
27., 42., 48., 32., 41., 5., 40., 33., 10., 11., 17., 13., 47.,
28., 5., 24., 26., 10., 49., 21., 14., 12., 3., 43., 8., 17.,
2., 1., 25., 48., 25., 46., 36., 18., 42., 31., 49., 37., 2.,
25., 47., 28., 9., 49., 10., 44., 12.])
1
2
3
4# 步骤2: 计算正方形的边长
n = int(np.floor(arr_qualified.shape[0]**.5))
n
输出(plain):
8
1
2
3
4# 步骤3: 整形为要求的正方形
top_indexes = np.argsort(arr_qualified)[::-1]
output = np.take(arr_qualified, sorted(top_indexes[:n**2])).reshape(n, -1)
print(output)
输出(stream):
[[12. 14. 33. 46. 7. 23. 13. 22.]
[35. 8. 34. 19. 49. 18. 22. 38.]
[27. 34. 47. 21. 9. 45. 18. 27.]
[42. 48. 32. 41. 40. 33. 10. 11.]
[17. 13. 47. 28. 24. 26. 10. 49.]
[21. 14. 12. 43. 8. 17. 25. 48.]
[25. 46. 36. 18. 42. 31. 49. 37.]
[25. 47. 28. 9. 49. 10. 44. 12.]]
交换dataframe的两行
把第一行和第二行数据交换
1
2df = pd.DataFrame(np.arange(25).reshape(5, -1))
df
输出(html):
0
1
2
3
4
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
20
21
22
23
24
1
2
3a, b = df.iloc[1, :].copy(), df.iloc[2, :].copy()
df.iloc[1, :], df.iloc[2, :] = b, a
df
输出(html):
0
1
2
3
4
0
0
1
2
3
4
1
10
11
12
13
14
2
5
6
7
8
9
3
15
16
17
18
19
4
20
21
22
23
24
dataframe行倒序排序1df.iloc[::-1, :]
输出(html):
0
1
2
3
4
4
20
21
22
23
24
3
15
16
17
18
19
2
5
6
7
8
9
1
10
11
12
13
14
0
0
1
2
3
4
对分类数据进行one-hot编码
经常用于逻辑回归
1
2df = pd.DataFrame(np.arange(25).reshape(5,-1), columns=list('abcde'))
df
输出(html):
a
b
c
d
e
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
20
21
22
23
24
1pd.concat([pd.get_dummies(df['a']), df[list('bcde')]], axis=1)
输出(html):
0
5
10
15
20
b
c
d
e
0
1
0
0
0
0
1
2
3
4
1
0
1
0
0
0
6
7
8
9
2
0
0
1
0
0
11
12
13
14
3
0
0
0
1
0
16
17
18
19
4
0
0
0
0
1
21
22
23
24
哪个列包含每行的最大值
求行最大值所在的列
1
2df = pd.DataFrame(np.random.randint(1,100, 40).reshape(10, -1))
df.apply(np.argmax, axis=1)
输出(stream):
d:\mysites\deeplearning.ai-master\.env\lib\site-packages\numpy\core\fromnumeric.py:52: FutureWarning: 'argmax' is deprecated, use 'idxmax' instead. The behavior of 'argmax'
will be corrected to return the positional maximum in the future.
Use 'series.values.argmax' to get the position of the maximum now.
return getattr(obj, method)(*args, **kwds)
输出(plain):
0 3
1 1
2 3
3 0
4 2
5 0
6 0
7 2
8 2
9 0
dtype: int64
计算 每行的最近行(使用欧几里得距离)1
2
3
4
5
6
7
8nearest = {}
for i, row in df.iterrows():
c = ((df - row)**2).sum(axis = 1).argsort()
for j in c:
if j != i:
break
nearest[i] = j
print(nearest)
输出(stream):
{0: 7, 1: 7, 2: 6, 3: 5, 4: 8, 5: 4, 6: 2, 7: 0, 8: 4, 9: 3}
今天的教程就到此为止了, 希望大家关注我的小站mlln.cn, 后面还会有关于pandas系列的练习题, 希望这些工作能帮助你学习pandas. 如果你有什么意见或者建议, 请在微博@该用户已经被封, 并附带本文链接。
注意
本文由jupyter notebook转换而来, 您可以在这里下载notebook
有问题可以直接在下方留言
或者给我发邮件675495787[at]qq.com
请记住我的网址: mlln.cn 或者 jupyter.cn