推荐书: Python开发最佳实践

pandas数据分析100道练习题-第四部分

分享时@该用户已经被封, 我就能回答你的问题奥!

文章目录
  1. 1. 如何计算列之间的最大相关系数
  2. 2. 计算每一行的最小值与最大值的比值
  3. 3. 找到每行第二大的值
  4. 4. 如何正态化dataframe中的所有列
  5. 5. 如何计算每行与上一行的相关?
  6. 6. 如何用0填充dataframe的对角线上的数
  7. 7. dataframe分组后获取某个组的数据
  8. 8. 分组后获取某组中的第n大的值
  9. 9. 分组后获取每组平均值, 并且保持分组列不是index
  10. 10. 参照两列合并两个dataframe, 并且只保留两个dataframe都有的行
  11. 11. 如何从dataframe中删除另一个dataframe中存在的行
  12. 12. 如何获得两列值匹配的位置
  13. 13. 时间序列如何前后移动时间步
  14. 14. 获取整个dataframe值的计数
  15. 15. 字符串列的分割


这篇文章收集了网友们使用pandas进行数据分析时经常遇到的问题, 这些问题也可以检验你使用pandas的熟练程度, 所以他们更像是一个学习教材, 掌握这些技能, 可以使你数据数据分析的工作事半功倍。

下面是第四部分:

如何计算列之间的最大相关系数

1
2
3
4
5
6
7
8
9
10
11
12
import pandas as pd
import numpy as np
df = pd.DataFrame(
np.random.randint(1,100, 80).reshape(8, -1),
columns=list('pqrstuvwxy'),
index=list('abcdefgh')
)

abs_corrmat = np.abs(df.corr())
print(abs_corrmat)
max_corr = abs_corrmat.apply(lambda x: sorted(x)[-2])
print('Maximum Correlation possible for each column: ', np.round(max_corr.tolist(), 2))
输出(stream):
p q r s t u v \
p 1.000000 0.268096 0.000000 0.552086 0.147951 0.229566 0.312353
q 0.268096 1.000000 0.881994 0.169709 0.124291 0.542839 0.351897
r 0.000000 0.881994 1.000000 0.254703 0.014796 0.335214 0.331702
s 0.552086 0.169709 0.254703 1.000000 0.373359 0.355978 0.042473
t 0.147951 0.124291 0.014796 0.373359 1.000000 0.564365 0.001794
u 0.229566 0.542839 0.335214 0.355978 0.564365 1.000000 0.179641
v 0.312353 0.351897 0.331702 0.042473 0.001794 0.179641 1.000000
w 0.697658 0.343943 0.566769 0.424458 0.014227 0.489756 0.274991
x 0.254656 0.431052 0.539917 0.434953 0.368824 0.275014 0.056530
y 0.106323 0.121851 0.179469 0.236219 0.228056 0.141275 0.468257

w x y
p 0.697658 0.254656 0.106323
q 0.343943 0.431052 0.121851
r 0.566769 0.539917 0.179469
s 0.424458 0.434953 0.236219
t 0.014227 0.368824 0.228056
u 0.489756 0.275014 0.141275
v 0.274991 0.056530 0.468257
w 1.000000 0.065845 0.124048
x 0.065845 1.000000 0.364810
y 0.124048 0.364810 1.000000
Maximum Correlation possible for each column: [0.7 0.88 0.88 0.55 0.56 0.56 0.47 0.7 0.54 0.47]

计算每一行的最小值与最大值的比值

1
2
3
4
5
df = pd.DataFrame(np.random.randint(1,100, 80).reshape(8, -1))

# Solution 1
min_by_max = df.apply(lambda x: np.min(x)/np.max(x), axis=1)
min_by_max
输出(plain):
0 0.074468
1 0.013514
2 0.101010
3 0.457447
4 0.040404
5 0.081633
6 0.024096
7 0.163265
dtype: float64

找到每行第二大的值

创建一个新列’penultimate’,它具有每行df的第二大值。

1
2
3
4
5
6
7
# Input
df = pd.DataFrame(np.random.randint(1,100, 80).reshape(8, -1))

# Solution
out = df.apply(lambda x: x.sort_values().unique()[-2], axis=1)
df['penultimate'] = out
print(df)
输出(stream):
0 1 2 3 4 5 6 7 8 9 penultimate
0 89 42 65 63 4 24 41 72 79 66 79
1 76 28 17 53 42 21 93 81 5 39 81
2 66 92 18 93 99 74 71 85 84 42 93
3 59 53 72 13 1 88 95 92 70 68 92
4 97 56 64 76 78 36 80 10 94 14 94
5 48 92 39 42 1 26 32 7 48 90 90
6 17 4 70 22 44 52 39 84 67 52 70
7 38 44 46 12 24 23 28 85 87 82 85

如何正态化dataframe中的所有列

1
2
3
4
5
6
7
8
9
10
# Input
df = pd.DataFrame(np.random.randint(1,100, 80).reshape(8, -1))

# Solution Q1
out1 = df.apply(lambda x: ((x - x.mean())/x.std()).round(2))
print('Solution Q1\n',out1)

# Solution Q2
out2 = df.apply(lambda x: ((x.max() - x)/(x.max() - x.min())).round(2))
print('Solution Q2\n', out2)
输出(stream):
Solution Q1
0 1 2 3 4 5 6 7 8 9
0 0.25 1.05 1.21 0.39 -0.57 0.34 -0.42 -0.79 -1.18 0.90
1 -0.11 -0.12 1.24 0.07 1.15 -1.18 1.16 0.53 1.10 -0.32
2 -0.78 1.53 -1.54 -1.24 1.20 1.72 0.27 1.00 0.42 0.06
3 -0.04 0.81 -0.41 -1.14 -0.99 -0.40 -1.05 -1.06 -1.45 -1.28
4 -0.75 -1.05 -1.12 -0.05 1.20 -1.14 -1.22 -0.62 -0.09 0.15
5 -0.53 -0.63 0.43 1.48 -0.69 -0.40 -0.16 -1.10 -0.16 1.07
6 2.31 -0.60 0.01 1.17 -0.91 0.94 1.65 0.63 -0.09 0.95
7 -0.36 -1.02 0.18 -0.68 -0.40 0.12 -0.23 1.41 1.44 -1.54
Solution Q2
0 1 2 3 4 5 6 7 8 9
0 0.67 0.19 0.01 0.40 0.81 0.48 0.72 0.88 0.91 0.06
1 0.78 0.64 0.00 0.52 0.02 1.00 0.17 0.35 0.12 0.53
2 1.00 0.00 1.00 1.00 0.00 0.00 0.48 0.16 0.35 0.39
3 0.76 0.28 0.59 0.97 1.00 0.73 0.94 0.99 1.00 0.90
4 0.99 1.00 0.85 0.56 0.00 0.99 1.00 0.81 0.53 0.35
5 0.92 0.84 0.29 0.00 0.87 0.73 0.63 1.00 0.55 0.00
6 0.00 0.83 0.44 0.11 0.97 0.27 0.00 0.31 0.53 0.05
7 0.86 0.99 0.38 0.79 0.73 0.55 0.66 0.00 0.00 1.00

如何计算每行与上一行的相关?

1
2
3
4
5
# Input
df = pd.DataFrame(np.random.randint(1,100, 80).reshape(8, -1))

# Solution
[df.iloc[i].corr(df.iloc[i+1]).round(2) for i in range(df.shape[0])[:-1]]
输出(plain):
[-0.51, 0.11, -0.05, 0.02, 0.46, -0.69, -0.23]

如何用0填充dataframe的对角线上的数

1
2
3
4
5
6
7
df = pd.DataFrame(np.random.randint(1,100, 100).reshape(10, -1))

# Solution
for i in range(df.shape[0]):
df.iat[i, i] = 0
df.iat[df.shape[0]-i-1, i] = 0
df
输出(html):
0 1 2 3 4 5 6 7 8 9
0 0 71 61 38 97 22 93 36 47 0
1 11 0 11 86 46 20 60 60 0 38
2 71 88 0 11 92 25 98 0 17 69
3 27 57 2 0 49 83 0 27 3 94
4 1 33 61 52 0 0 50 71 96 29
5 2 52 32 90 0 0 59 53 15 52
6 1 41 90 0 42 52 0 14 17 39
7 42 87 0 51 54 84 29 0 94 99
8 29 0 64 64 7 99 47 39 0 62
9 0 71 1 20 27 54 37 99 31 0

dataframe分组后获取某个组的数据

1
2
3
4
5
6
7
8
df = pd.DataFrame({'col1': ['apple', 'banana', 'orange'] * 3,
'col2': np.random.rand(9),
'col3': np.random.randint(0, 15, 9)})

df_grouped = df.groupby(['col1'])

# Solution 1
df_grouped.get_group('apple')
输出(html):
col1 col2 col3
0 apple 0.861407 5
3 apple 0.407644 14
6 apple 0.974718 11

分组后获取某组中的第n大的值

1
2
3
4
5
6
7
8
df = pd.DataFrame({'fruit': ['apple', 'banana', 'orange'] * 3,
'taste': np.random.rand(9),
'price': np.random.randint(0, 15, 9)})

n=2
# Solution
df_grpd = df['taste'].groupby(df.fruit)
df_grpd.get_group('banana').sort_values().iloc[-n]
输出(plain):
0.31660034951387783

分组后获取每组平均值, 并且保持分组列不是index

1
2
3
4
5
6
7
df = pd.DataFrame({'fruit': ['apple', 'banana', 'orange'] * 3,
'rating': np.random.rand(9),
'price': np.random.randint(0, 15, 9)})

# Solution
out = df.groupby('fruit', as_index=False)['price'].mean()
print(out)
输出(stream):
fruit price
0 apple 6
1 banana 7
2 orange 5

参照两列合并两个dataframe, 并且只保留两个dataframe都有的行

1
2
3
4
5
6
7
8
9
10
df1 = pd.DataFrame({'fruit': ['apple', 'banana', 'orange'] * 3,
'weight': ['high', 'medium', 'low'] * 3,
'price': np.random.randint(0, 15, 9)})

df2 = pd.DataFrame({'pazham': ['apple', 'orange', 'pine'] * 2,
'kilo': ['high', 'low'] * 3,
'price': np.random.randint(0, 15, 6)})

# Solution
pd.merge(df1, df2, how='inner', left_on=['fruit', 'weight'], right_on=['pazham', 'kilo'], suffixes=['_left', '_right'])
输出(html):
fruit weight price_left pazham kilo price_right
0 apple high 14 apple high 4
1 apple high 9 apple high 4
2 apple high 10 apple high 4
3 orange low 7 orange low 11
4 orange low 8 orange low 11
5 orange low 14 orange low 11

如何从dataframe中删除另一个dataframe中存在的行

1
2
3
4
5
6
7
8
9
10
11
12
13
df1 = pd.DataFrame({'fruit': ['apple', 'orange', 'banana'] * 3,
'weight': ['high', 'medium', 'low'] * 3,
'price': np.arange(9)})

df2 = pd.DataFrame({'fruit': ['apple', 'orange', 'pine'] * 2,
'weight': ['high', 'medium'] * 3,
'price': np.arange(6)})


# Solution
print(df1[~df1.isin(df2).all(1)])

df1.isin(df2)
输出(stream):
fruit weight price
2 banana low 2
3 apple high 3
4 orange medium 4
5 banana low 5
6 apple high 6
7 orange medium 7
8 banana low 8
输出(html):
fruit weight price
0 True True True
1 True True True
2 False False True
3 True False True
4 True False True
5 False False True
6 False False False
7 False False False
8 False False False

如何获得两列值匹配的位置

1
2
3
4
5
df = pd.DataFrame({'fruit1': np.random.choice(['apple', 'orange', 'banana'], 10),
'fruit2': np.random.choice(['apple', 'orange', 'banana'], 10)})

# Solution
np.where(df.fruit1 == df.fruit2)
输出(plain):
(array([1, 2, 5, 6, 7, 8], dtype=int64),)

时间序列如何前后移动时间步

创建新的列是已有列的滞后列或者前向列

1
2
3
4
5
6
df = pd.DataFrame(np.random.randint(1, 100, 20).reshape(-1, 4), columns = list('abcd'))

# Solution
df['a_lag1'] = df['a'].shift(1)
df['b_lead1'] = df['b'].shift(-1)
print(df)
输出(stream):
a b c d a_lag1 b_lead1
0 90 49 33 17 NaN 11.0
1 84 11 34 16 90.0 66.0
2 78 66 63 6 84.0 34.0
3 84 34 53 15 78.0 30.0
4 12 30 44 22 84.0 NaN

获取整个dataframe值的计数

1
2
3
4
df = pd.DataFrame(np.random.randint(1, 10, 20).reshape(-1, 4), columns = list('abcd'))
# Solution

pd.value_counts(df.values.ravel())
输出(plain):
2 4
8 3
5 3
1 3
4 2
3 2
9 1
7 1
6 1
dtype: int64

字符串列的分割

1
2
3
4
5
6
7
8
df = pd.DataFrame(["STD, City    State",
"33, Kolkata West Bengal",
"44, Chennai Tamil Nadu",
"40, Hyderabad Telengana",
"80, Bangalore Karnataka"], columns=['row'])

# Solution
df.row.str.split(',|\t', expand=True)
输出(html):
0 1
0 STD City State
1 33 Kolkata West Bengal
2 44 Chennai Tamil Nadu
3 40 Hyderabad Telengana
4 80 Bangalore Karnataka

注意
本文由jupyter notebook转换而来, 您可以在这里下载notebook
有问题可以直接在下方留言
或者给我发邮件675495787[at]qq.com
请记住我的网址: mlln.cn 或者 jupyter.cn