发布于 ,更新于 

笔记:pandas 的常用操作

示例来自 Kaggle 的 Pandas 课程。

读取和写入文件

1
reviews = pd.read_csv("../input/wine-reviews/winemag-data_first150k.csv", index_col=0)
  • index_col=0:将第一列作为索引。在 csv 的某一列已经是数字编号 (0, 1, 2, …) 的情况下使用。
1
reviews.to_csv("filename.csv")

索引和选择

二维 DataFrame 的索引方式:先行后列,用逗号分隔。只选择行,则不需要写出列名。: 表示所有行。

iloc

iloc 用行/列的数字位置 (0, 1, 2, …) 来索引,类似于 Python 原生的列表索引,左闭右开。

1
2
3
4
5
6
reviews.iloc[0] # 取出第一行
reviews.description.iloc[0] # 取出 description 列的第一行
reviews.iloc[-5:] # 取出最后五行

reviews.iloc[:, 0] # 取出第一列
reviews.iloc[1:3, 0] # 取出第 1-2 行的第一列

loc

loc 用行/列标签来索引,索引是左闭右闭的,除了数字,也可以取字符串区间。

1
2
3
reviews.loc[:9, "description"] # 取出第 0-9 行的 description 列
# description 是第 1 列 (0-indexed),因此上述代码等价于
reviews.iloc[:10, 1]

条件选择

1
reviews.loc[(reviews.country == 'Italy') & (reviews.points >= 90)]

运算符:& (and)、| (or)、~ (not)。

1
reviews.loc[reviews.country.isin(['Italy', 'France'])]
  • isin:判断值是否在列表中。
1
reviews.loc[reviews.price.notnull()]
  • isnull:判断是否为 NaN。

统计综述

  • count, mean, median, min, max, std:常用的统计量。忽略 NaN。
  • describe:返回上述统计量的汇总。
  • idxmax, idxmin:返回最大/最小值的索引。
  • unique:返回所有唯一值构成的列表。即去重。
  • value_counts:返回每个值出现的次数。

映射

1
2
rpm = reviews.price.mean()
centered_price = reviews.price.map(lambda p: p - rpm)

返回一个 Series,索引与原来相同,值为函数的返回值。

1
2
bargain_idx = (reviews.points / reviews.price).idxmax()
bargain_wine = reviews.loc[bargain_idx, 'title']

列和列的运算结果仍然是 Series,因此可以使用 idxmax 等方法。

使用操作符运算类似于 apply,可以让一行中的多列数据参与运算,但是速度更快。

1
2
3
4
5
6
7
8
9
def star(row):
if row.country == "Canada" or row.points >= 95:
return 3
elif row.points >= 85:
return 2
else:
return 1

star_ratings = reviews.apply(star, axis="columns")
  • apply:对每一行/列应用函数。默认按列,axis="columns" 按行。返回一个 Series。

分组和排序

1
reviews.groupby('points').points.count()

按照 points 列的值进行分组,然后对每组的 points 列进行计数。也就是输出每个 points 值出现的次数。

1
2
country_provinces = reviews.groupby(['country', 'province'])
country_provinces.apply(lambda df: df.loc[df.points.idxmax()])

选出每个 country-province 组合中 points 最大的行。

1
country_provinces.reset_index()

将 country-province 的 MultiIndex 从索引中移除,拆分为两个普通的列。然后自动添加 0-indexed 的列索引。

1
reviews.groupby(['country']).price.agg([len, min, max])

按照 country 分组,输出每组的记录数、price 列的最小值和最大值。

  • agg:对每一列应用多个函数。此处的 len 是 Python 的内置函数。
1
2
3
countries_reviewed = country_provinces.agg({'points': ['len', 'mean'], 'price': ['min', 'max']})
countries_reviewed.reset_index()
countries_reviewed.sort_values(by=[('points', 'mean')])

对多列使用 agg,生成了一个行方向上的 MultiIndex。因此需要使用元组来索引,如 ('points', 'mean')

  • sort_values:按照指定列的值进行排序。默认升序,ascending=False 降序。
1
countries_reviewed.sort_index()

按照列索引进行排序。

数据类型和缺失值

1
reviews.points.astype('float64')

将 points 列的数据类型转换为 float64。

一般地,整数使用 int64,浮点数使用 float64,字符串使用 object

1
reviews.region_2.fillna("Unknown")

将 region_2 列中的 NaN 填充为 “Unknown”。

1
reviews.taster_twitter_handle.replace("@kerinokeefe", "@kerino")

批量替换。

重命名和合并表

1
reviews.rename(columns={'points': 'score'})

将 points 列重命名为 score。

1
2
3
4
canadian_youtube = pd.read_csv("../input/youtube-new/CAvideos.csv")
british_youtube = pd.read_csv("../input/youtube-new/GBvideos.csv")

pd.concat([canadian_youtube, british_youtube])
  • concat:将作为 list 传递的多个 DataFrame 按行拼接(即纵向堆叠,行数相加)。
1
2
3
4
powerlifting_meets = pd.read_csv("../input/powerlifting-database/meets.csv")
powerlifting_competitors = pd.read_csv("../input/powerlifting-database/openpowerlifting.csv")

powerlifting_combined = powerlifting_meets.set_index('MeetID').join(powerlifting_competitors.set_index('MeetID'))
  • join:将两个 DataFrame 按照指定的列进行合并(如果表 powerlifting_meetspowerlifting_competitors 中的两行具有相同的 MeetID,则合并为一行,保留两张表中的其他所有列)。

使用 lsuffixrsuffix 来处理两个表中列名相同但含义不同的列。