博文名称:30 Very Useful Pandas Functions for Everyday Data Analysis Tasks
博文链接:https://towardsdatascience.com/30-very-useful-pandas-functions-for-everyday-data-analysis-tasks-f1eae16409af
发表时间:Jan 5, 2022
Python的Pandas库是Python中使用最广泛的库。因为这是数据分析或机器学习的各个方面所必需的数据操作库。即使你正在从事数据可视化或机器学习,无论如何都会进行一些数据操作。在本文中,我将列出日常使用所需的Pandas函数,这些函数可以说足以满足常规的数据操作任务。
在本文中,我将使用Kaggle的一个公共数据集,称为FIFA数据集。此处提到了用户许可证。
请随时从此处下载数据集:
Datasets/fifa.csv at master · rashida048/Datasets
让我们开始操作数据吧!
导入必要的包和数据集:
import numpy as np
import pandas as pd
pd.set_option('display.max_columns', 100)
让我们开始讨论以下函数:
1. pd.read_csv, pd.read_excel
要提到的第一个函数是read_csv和read_excel。到现在为止,我在每个项目中都至少使用了其中一个功能。这些功能已经一目了然。它们用于将CSV或excel文件读取为Pandas的DataFrame格式。这里我使用read_csv函数来读取FIFA数据集:
df = pd.read_csv("fifa.csv")
有关read_csv函数的详细视频详见以下链接。它有几个很好的参数,可以帮助你在读取数据集时稍微清理一下数据集。我在这里有一篇详细的文章:
Import CSV Files As Pandas DataFrame With skiprows, skipfooter, usecols, index_col, and header…
也可以使用 .read_csv() 函数执行以下代码读取.txt文件:
data = pd.read_csv(file.txt, sep=" ")
如果你有一个excel文件而不是一个csv文件,你将使用pd.read_excel。
在read_csv或read_excel之后使用.head()函数来查看数据框的数据。默认情况下,它显示DataFrame的前5行。在这里,我展示了上面数据框df的前五行:
df.head()
如果你想要特定的行数而不是默认的行数,你可以指定它。如果我想要7行,我会在.head()函数中传入参数。
df.head(7)
2. df.columns
你有一个像这样的大数据集时,很难看到所有的列。使用.columns函数,你可以打印出数据集的所有列:
df.columns
输出:
Index(['Unnamed: 0', 'sofifa_id', 'player_url', 'short_name', 'long_name', 'age', 'dob', 'height_cm', 'weight_kg', 'nationality', 'club_name', 'league_name', 'league_rank', 'overall', 'potential', 'value_eur', 'wage_eur', 'player_positions', 'preferred_foot', 'international_reputation', 'weak_foot', 'skill_moves', 'work_rate', 'body_type', 'real_face', 'release_clause_eur', 'player_tags', 'team_position', 'team_jersey_number', 'loaned_from', 'joined', 'contract_valid_until', 'nation_position', 'nation_jersey_number', 'pace', 'shooting', 'passing', 'dribbling', 'defending', 'physic', 'gk_diving', 'gk_handling', 'gk_kicking', 'gk_reflexes', 'gk_speed', 'gk_positioning', 'player_traits', 'attacking_crossing', 'attacking_finishing', 'attacking_heading_accuracy', 'attacking_short_passing', 'attacking_volleys', 'skill_dribbling', 'skill_curve', 'skill_fk_accuracy', 'skill_long_passing', 'skill_ball_control', 'movement_acceleration', 'movement_sprint_speed', 'movement_agility', 'movement_reactions', 'movement_balance', 'power_shot_power', 'power_jumping', 'power_stamina', 'power_strength', 'power_long_shots', 'mentality_aggression', 'mentality_interceptions', 'mentality_positioning', 'mentality_vision', 'mentality_penalties',
'mentality_composure', 'defending_marking', 'defending_standing_tackle', 'defending_sliding_tackle', 'goalkeeping_diving', 'goalkeeping_handling', 'goalkeeping_kicking', 'goalkeeping_positioning', 'goalkeeping_reflexes'], dtype='object')
3. df.drop()
你可以使用df.drop()删除一些不必要的列。在这个数据集中,我们有很多列,我们在本教程中不会使用所有列。因此,我们可以轻松删除一些:
df = df.drop(columns=['Unnamed: 0', 'weak_foot', 'real_face'])
我刚刚删除了这三列:'Unnamed: 0'、'weak_foot'、'real_face'。
4. .len()
提供DataFrame的长度。让我们看一个例子:
len(df)
输出:
16155
这个DataFrame有16155行数据。
5. df.query()
你可以使用布尔表达式进行过滤或查询。我将在此示例中使用“投篮”和“传球”列。在这里,我正在检查哪些行 'shooting' 大于 'passing'。
df.query("shooting > passing")
这将仅返回投篮大于传球的行。
6. df.iloc()
该函数将行和列索引作为参数,并相应地为你提供DataFrame的子集。在这里,我将提取前10行和列索引为5到10的数据:
df.iloc[:10, 5:10]
7. df.loc()
该函数执行的操作几乎与 .iloc() 函数类似。但是在这里,我们可以准确地指定我们想要的行索引以及列的名称。下面是一个例子:
df.loc[[3, 10, 14, 23], ['nationality', 'weight_kg', "height_cm"]]
查看行索引,我们只提取第 3、10、14和 23行。另外,对于列,我们只有指定的列。
8. df[‘’].dtypes
另一个非常基础和广泛使用的函数。因为在我们深入分析、可视化或预测建模之前,有必要了解变量的数据类型。我在这里使用 .dtypes函数获取“height_cm”列的数据类型:
df.height_cm.dtypes
输出:
dtype('int64')
你还可以选择使用以下代码获取每一列的数据类型:
df.dtypes
输出:
height_cm int64weight_kg int64nationality objectrandom_col int32club_name objectleague_name objectleague_rank float64overall int64potential int64value_eur int64wage_eur int64player_positions objectpreferred_foot objectinternational_reputation int64skill_moves int64work_rate objectbody_type objectteam_position objectteam_jersey_number float64nation_position objectnation_jersey_number float64pace float64shooting float64passing float64dribbling float64defending float64physic float64cumsum_2 int64rank_calc float64dtype: object
9. df.select_dtypes()
你可以使用此函数选择特定数据类型的变量或列。例如,我只想选择数据类型为“int64”的列。以下是如何做到这一点:
df.select_dtypes(include='int64')
我们得到了所有数据类型为“int64”的列。如果我们在 'select_dtypes' 函数中使用 'exclude' 而不是 'include',我们将得到数据类型不是 'int64' 类型的列:
df.select_dtypes(exclude='int64')
这是输出的一部分。可以看到,输出的变量不是整数。但是,你可能认为 'random_col' 列是整数。但是如果你检查它的数据类型,你会发现它看起来是整数,但实际它的数据类型是不同的。请随时检查。
10. df.insert()
顾名思义,它在指定位置插入一列。为了演示,我将首先创建一个跟我们数据框长度相同的随机数数组:
random_col = np.random.randint(100, size=len(df))
我将这个数组作为一列插入到数据框 df 的第 3 列位置。请记住,列索引从零开始。
df.insert(3, 'random_col', random_col)
查看数据框:
df.head()
可以看到, 'random_col' 列插入到第三列。
11. df[‘’].cumsum()
提供累计金额。让我用一个例子来解释。我将在此示例中使用“value_eur”和“wage_eur”列。下面是代码:
df[['value_eur', 'wage_eur']].cumsum()
输出:
正如你在每一行中看到的那样,它为你提供前一行所有值的累积总和。
12. df.sample()
当数据集太大时,可以从中提取代表性样本来执行分析和预测建模。这可能会节省你一些时间。此外,过多的数据有时可能会破坏可视化。我们可以使用此函数来获得一定数量的数据点或一定比例数据点。在这里,我从FIFA数据集中抽取了200个数据点的样本。它需要随机抽样。
df.sample(n = 200)
我在这里使用 25% 的 FIFA 数据集:
df.sample(frac = 0.25)
13. df[‘’].where()
此函数可帮助你根据布尔条件查询数据集。举个例子,我们之前添加的random_col列数值范围是0到100。 下面是我们看看哪些值大于50。
df['random_col'].where(df['random_col'] > 50)
输出:
0 NaN
1 NaN
2 56.0
3 NaN
4 NaN
...
16150 65.0
16151 NaN
16152 NaN
16153 57.0
16154 NaN
Name: random_col, Length: 16155, dtype: float64
可以看到,如果值不满足不大于 50 的条件,则返回 NaN。我们可以使用以下代码将NaN替换为0或任何其他值:
df['random_col'].where(df['random_col'] > 50, 0)
输出:
0 0
1 0
2 56
3 0
4 0
..
16150 65
16151 0
16152 0
16153 57
16154 0
Name: random_col, Length: 16155, dtype: int32
14. df[‘’].unique()
这对分类变量非常有用。它用于查找分类列的唯一值。让我们看看FIFA数据集中“skill_moves”列的唯一值是什么:
df.skill_moves.unique()
输出:
array([4, 5, 1, 3, 2], dtype=int64)
可以看到,Skill_moves列有五个唯一值。如果我们打印出数据集的头部来检查列的值,可能看不到其中的所有唯一值。所以,要知道所有的唯一值, .unique()函数真的很方便。
15. df[‘’].nunique()
另一个主流的函数。此函数可让你知道一列中有多少个唯一值。例如,如果你想查看此数据集中有多少不同的国籍,可以使用这行简单的代码:
df.nationality.nunique()
输出:
149
很棒的一点是,这个函数也可以用于整个数据集,以了解每列中唯一值的数量:
df.nunique()
输出:
height_cm 48
weight_kg 54
nationality 149
random_col 100
club_name 577
league_name 37
league_rank 4
overall 53
potential 49
value_eur 161
wage_eur 41
player_positions 907
preferred_foot 2
international_reputation 5
skill_moves 5
work_rate 9
body_type 3
team_position 29
team_jersey_number 99
nation_position 28
nation_jersey_number 26
pace 74
shooting 70
passing 67
dribbling 67
defending 69
physic 63
cumsum_2 14859
rank_calc 161
dtype: int64
上面我们得到每列中唯一值的数目。
16. df[‘’].rank()
该函数为你提供基于特定列的排名。在 FIFA 数据集中,如果我们想根据 ‘value_eur’ 列对球员进行排名,代码如下:
df['rank_calc'] = df["value_eur"].rank()
使用上面的代码,创建了一个名为“rank_calc”的新列。这个新列将根据“value_eur”为你提供每个运动员的排名。默认情况下,该列将添加到最后。请自行运行该行代码进行检查。
17. .isin()
我将使用 .isin() 函数提取仅包含少数国籍的运动员的数据集子集。
nationality = ["Argentina", "Portugal", "Sweden", "England"]
df[df.nationality.isin(nationality)]
运行这段代码,你将看到我们得到的数据集只包含上面列表中提到的几个国家。可以在此处看到提取的子集:
18. df.replace()
replace函数将替换列的值。当我们只需要替换列的一个唯一值时,我们只需要传递旧值和新值。现在,我们将“league_rank”1.0替换成1.1。
df.replace(1.0, 1.1)
现在看数据集中的League_rank列,1.0 被1.1取代。如果我们需要更改多个值,我们可以通过字典传递给替换函数,其中键应该是原始值,值应该是替换值。
df.replace({1.0: 1.1, 4.0: 4.1, 3.0: 3.1})
19. df.rename()
它用于对表的列重命名。在此,我将“weight_kg”和“height_cm”列更改为Weight (kg)”和“Height (cm)”:
df.rename(columns = {"weight_kg": "Weight (kg)", "height_cm": "Height (cm)"})
非常简单有用!
20. .fillna()
每当你在现实生活中收到一个大数据集时,在大多数情况下,都会有一些空值。得到一个完美的数据集很难。因此,如果你是数据分析师或数据科学家,空值填补是你日常任务的一部分。此函数 .fillna() 用你选择的其他值替换空值。以下是FIFA数据集末尾的一些列:
可以看到,在投篮、传球、防守和其他一些列中有一些空值。在开始进行任何预测建模和其他一些数据科学任务之前,我们确实需要用一些兼容数据类型的值替换这些空值。否则,我们可能会出错。例如,在‘pace’列中,值应该是数字,但你会看到NaN值。最通用但不是那么有效的方法是用零值替换这些NaN值。
df['pace'].fillna(0, inplace=True)
你会注意到,现在“pace”列中的NaN转为零。在“total pace”列中,如果有更多NaN值,它们也应该用零替换。
正如我之前提到的,用零替换可能不是最有效的方法。你可以将其替换为您选择的其他一些值。用平均值或中位数替换值也很常见。
df['pace'].fillna(df['pace'].mean(), inplace = True)
21. df.groupby()
这是最主流的数据汇总函数。可以根据某个变量对数据进行分组,并找出有关这些组的有用信息。例如,这里按国籍对数据进行分组并计算每个国籍的总“value_eur”:
df.groupby("nationality")['value_eur'].sum()
输出:
nationality
Albania 25860000
Algeria 70560000
Angola 6070000
Antigua & Barbuda 1450000
Argentina 1281372000
...
Uzbekistan 7495000
Venezuela 41495000
Wales 113340000
Zambia 4375000
Zimbabwe 6000000
Name: value_eur, Length: 149, dtype: int64
阿尔巴尼亚所有球员的'value_eur'总和为25860000。
也可以按多个变量分组并使用多个聚合函数。我们将看到每个国籍和每个联赛排名的均值_eur、中值_eur、均值工资_eur和中值工资_eur。
df.groupby(['nationality', 'league_rank'])['value_eur', 'wage_eur'].agg([np.mean, np.median])
输出:
可以使用“group by”函数执行更多操作。我在这里有一篇详细的文章:
Efficient Data Summarizing and Analysis Using Pandas’ Groupby Function
22. .pct_change()
你可以计算变量较先前值的变化百分比。在本演示中,我将使用 value_eur列并获取每行数据相对于前一列的百分比变化。第一行将是NaN,因为之前没有要比较的值。
df.value_eur.pct_change()
输出:
0 NaN
1 -0.213930
2 -0.310127
3 -0.036697
4 0.209524
...
16150 0.000000
16151 0.500000
16152 -0.500000
16153 0.000000
16154 -1.000000
Name: value_eur, Length: 16155, dtype: float64
在这个数据集中,你可能不觉得这很重要。
但想想一些财务数据。特别是当您每天拥有股票市场价值时。看到每天价值的百分比变化该有多好。
23. df.count()
它为你提供数据框中指定方向的数据数量。当方向为0时,它提供数据框列的数据数目:
df.count(0)
输出:
Unnamed: 0 16155
sofifa_id 16155
player_url 16155
short_name 16155
long_name 16155
...
goalkeeping_diving 16155
goalkeeping_handling 16155
goalkeeping_kicking 16155
goalkeeping_positioning 16155
goalkeeping_reflexes 16155
Length: 81, dtype: int64
你可以看到每列中的数据数量。
当方向为1时,它提供行中的数据数:
df.count(1)
输出:
0 72
1 72
2 72
3 72
4 71
..
16150 68
16151 68
16152 68
16153 68
16154 69
Length: 16155, dtype: int64
每一行的数据数量不同。如果你仔细观察数据集,你会发现它在几列中有很多空值。
24. df[‘’].value_counts()
我们可以使用此函数获取每个类别的值计数。在这里,我得到了每个League_rank中有多少个值。
df['league_rank'].value_counts()
输出:
1.0 11738
2.0 2936
3.0 639
4.0 603
Name: league_rank, dtype: int64
它返回默认排序的结果。如果你希望结果按升序排列,只需设置升序 = True:
df['league_rank'].value_counts(ascending=True)
输出:
4.0 603
3.0 639
2.0 2936
1.0 11738
Name: league_rank, dtype: int64
25. pd.crosstab()
它提供了一个频率表,它是两个变量的交叉表。我在这里制作了 League_rank 和 international_reputation 的交叉表:
pd.crosstab(df['league_rank'], df['international_reputation'])
所以,我们得到了League_rank和international_reputation所有组合的数量。我们可以看到大多数球员的international_reputation 和 League_rank都为 1。
可以进一步改进。我们可以在两个方向上添加累计值,必要时还可以获得标准化值:
pd.crosstab(df['league_rank'], df['international_reputation'],
margins = True,
margins_name="Total",
normalize = True)
下面是关于 count、value_counts 和 crosstab 方法的详细教程:
Three Very Useful Functions of Pandas to Summarize the Data
26. pd.qcut()
该函数根据数据的分布对数据进行分箱或分段。所以,我们得到了每个球员的分组。在这里,我将 value_eur分为5个部分,并获取哪个球员属于哪个部分:
pd.qcut(df['value_eur'], q = 5)
输出:
0 (1100000.0, 100500000.0]
1 (1100000.0, 100500000.0]
2 (1100000.0, 100500000.0]
3 (1100000.0, 100500000.0]
4 (1100000.0, 100500000.0]
...
16150 (-0.001, 100000.0]
16151 (-0.001, 100000.0]
16152 (-0.001, 100000.0]
16153 (-0.001, 100000.0]
16154 (-0.001, 100000.0]
Name: value_eur, Length: 16155, dtype: category
Categories (5, interval[float64]): [(-0.001, 100000.0] < (100000.0, 230000.0] < (230000.0, 500000.0] < (500000.0, 1100000.0] < (1100000.0, 100500000.0]]
您可以使用上述代码行中的 value_counts 来查看球员如何落入哪个范围:
pd.qcut(df['value_eur'], q = 5).value_counts()
输出:
(-0.001, 100000.0] 3462
(230000.0, 500000.0] 3305
(100000.0, 230000.0] 3184
(500000.0, 1100000.0] 3154
(1100000.0, 100500000.0] 3050
Name: value_eur, dtype: int64
如你所见,数字非常接近。默认情况下,qcut尝试将它们平均划分。但在现实生活中,它并不希望总是平等。因为大多数时候分布并不均匀。
27. pd.cut()
分档的另一种方法。如果我们想使用cut制作5个bin,它会将整个value_eur范围分成相等的五个部分,每个 bin 中的数目将相应地跟随。
pd.cut(df['value_eur'], bins = 5).value_counts()
输出:
(-100500.0, 20100000.0] 16102
(20100000.0, 40200000.0] 40
(40200000.0, 60300000.0] 10
(60300000.0, 80400000.0] 2
(80400000.0, 100500000.0] 1
Name: value_eur, dtype: int64
每个区间的区间相等,但是每个分组的数目是非常不同的。
我有一篇关于使用 cut 和 qcut 方法进行数据分箱的详细文章。请随意查看:
Data Binning with Pandas Cut or Qcut Method
28. df[‘’].describe()
这是一个很好的函数,它提供了一些基本的统计度量。我在这里使用了wage_eur 列上的describe 函数:
df['wage_eur'].describe()
输出:
count 16155.000000
mean 13056.453110
std 23488.182571
min 0.000000
25% 2000.000000
50% 5000.000000
75% 10000.000000
max 550000.000000
Name: wage_eur, dtype: float64
如输出所示,我们有八种不同的度量。它们中的每一个都非常重要。
29. nlargest and nsmallest
这为你提供了具有指定变量的n个最大值或最小值的数据集。例如,我想获取前5位工资的行:
df.nlargest(5, "wage_eur")
以同样的方式,我可以用5个最小的wage_eur数据制作数据集的子集:
df.nsmallest(5, "wage_eur")
30. df.explode()
当某些行中有数据列表时,分解会很有用。当某些列中有整数而某些列中有列表时,很难分析、可视化或执行某些预测建模。Explode函数有助于分解这些列表。例如,看看这个数据框:
将dataframe按照某一指定列进行展开,使得原来的每一行展开成一行或多行。
df1 = pd.DataFrame({"city": ['A', 'B', 'C'],
"day1": [22, 25, 21],
'day2':[31, 12, 67],
'day3': [27, 20, 15],
'day4': [34, 37, [41, 45, 67, 90, 21]],
'day5': [23, 54, 36]})
df1
让我们扩展d4列:
df1.explode(jupyter notebook'day4').reset_index(drop=True)
结论
Python的panda的库很强大,有这么多功能。我在日常生活中选择了一些重要的功能。如果你非常了解这些,你将能够成功执行大多数分析任务。Panda还有一个非常有用的函数,我在这里没有提到,那就是 .plot() 函数。你通过pandas就可绘图。Pandas在后端使用Matplotlib并为你返回绘图。我在这里有一个详细的教程: