虽然我们可以通过数据选择方法从一个完整的数据集中拿到我们需要的数据,但有的时候直接删除不需要的数据更加简单直接。Pandas 中,以 .drop
开头的方法都与数据删减有关。
DataFrame.drop
可以直接去掉数据集中指定的列和行。一般在使用时,我们指定 labels
标签参数,然后再通过 axis
指定按列或按行删除即可。当然,你也可以通过索引参数删除数据,具体查看官方文档。
axis=0
或 axis='index'
:删除行。这是默认设置。axis=1
或 axis='columns'
:删除列。df.drop(labels=['Median Age', 'Total Males'], axis=1)
DataFrame.drop_duplicates
则通常用于数据去重,即剔除数据集中的重复值。使用方法非常简单,默认情况下,它会根据所有列删除重复的行。也可以使用 subset 指定要删除的特定列上的重复项,要删除重复项并保留最后一次出现,请使用 keep=‘last’。
一个删除列的例子
在 Pandas 中,删除 DataFrame 的列通常通过指定列的名称来完成。你不需要直接写列数(索引),而是使用列的名称。例如,如果你的 DataFrame 是这样的:
import pandas as pd
data = {'A': [1, 2, 3], 'B': [4, 5, 6], 'C': [7, 8, 9]}
df = pd.DataFrame(data)
现在假设你想删除列 'B'
,你可以这样做:
df = df.drop('B', axis=1)
这里 'B'
是列的名称,axis=1
指定了你想删除的是列,而不是行(行是 axis=0
)。这种方法避免了直接使用列的数值索引,使代码更加清晰易懂。
[DataFrame.drop_duplicates
] 则通常用于数据去重,即剔除数据集中的重复值。使用方法非常简单,默认情况下,它会根据所有列删除重复的行。也可以使用 subset 指定要删除的特定列上的重复项,要删除重复项并保留最后一次出现,请使用 keep=‘last’。
除此之外,另一个用于数据删减的方法 [DataFrame.dropna
] 也十分常用,其主要的用途是删除缺少值,即数据集中空缺的数据列或行。
既然提到了数据删减,反之则可能会遇到数据填充的情况。而对于一个给定的数据集而言,我们一般不会乱填数据,而更多的是对缺失值进行填充。
在真实的生产环境中,我们需要处理的数据文件往往没有想象中的那么美好。其中,很大几率会遇到的情况就是缺失值。缺失值主要是指数据丢失的现象,也就是数据集中的某一块数据不存在。除此之外、存在但明显不正确的数据也被归为缺失值一类。例如,在一个时间序列数据集中,某一段数据突然发生了时间流错乱,那么这一小块数据就是毫无意义的,可以被归为缺失值。
Pandas 为了更方便地检测缺失值,将不同类型数据的缺失均采用 NaN
标记。这里的 NaN 代表 Not a Number,它仅仅是作为一个标记。例外是,在时间序列里,时间戳的丢失采用 NaT
标记。
Pandas 中用于检测缺失值主要用到两个方法,分别是:isna()
和 notna()
,故名思意就是「是缺失值」和「不是缺失值」。默认会返回布尔值用于判断。
接下来,我们人为生成一组包含缺失值的示例数据。
df = pd.DataFrame(np.random.rand(9, 5), columns=list('ABCDE'))
# 插入 T 列,并打上时间戳
df.insert(value=pd.Timestamp('2017-10-1'), loc=0, column='Time')
# 将 1, 3, 5 列的 2,4,6,8 行置为缺失值
df.iloc[[1, 3, 5, 7], [0, 2, 4]] = np.nan
# 将 2, 4, 6 列的 3,5,7,9 行置为缺失值
df.iloc[[2, 4, 6, 8], [1, 3, 5]] = np.nan
df
Time | A | B | C | D | E | |
---|---|---|---|---|---|---|
0 | 2017-10-01 | 0.604915 | 0.205769 | 0.265589 | 0.133621 | 0.348693 |
1 | NaT | 0.731832 | NaN | 0.110929 | NaN | 0.430827 |
2 | 2017-10-01 | NaN | 0.243280 | NaN | 0.927472 | NaN |
3 | NaT | 0.514475 | NaN | 0.616544 | NaN | 0.314332 |
4 | 2017-10-01 | NaN | 0.951334 | NaN | 0.620587 | NaN |
5 | NaT | 0.279080 | NaN | 0.298142 | NaN | 0.527567 |
6 | 2017-10-01 | NaN | 0.345831 | NaN | 0.023264 | NaN |
7 | NaT | 0.522263 | NaN | 0.757472 | NaN | 0.072000 |
8 | 2017-10-01 | NaN | 0.928859 | NaN | 0.718561 | NaN |
首先,我们可以用相同的标量值替换 NaN
,比如用 0
。
df.fillna(0)
除了直接填充值,我们还可以通过参数,将缺失值前面或者后面的值填充给相应的缺失值。例如使用缺失值前面的值进行填充:
df.fillna(method='pad') #使用缺失值前面的数填补
df.fillna(method='bfill') #使用缺失值后面的数填补
上面的例子中,我们的缺失值是间隔存在的。那么,如果存在连续的缺失值是怎样的情况呢?试一试。首先,我们将数据集的第 2,4 ,6 列的第 3,5 行也置为缺失值。
df.iloc[[3, 5], [1, 3, 5]] = np.nan
df
Time | A | B | C | D | E | |
---|---|---|---|---|---|---|
0 | 2017-10-01 | 0.604915 | 0.205769 | 0.265589 | 0.133621 | 0.348693 |
1 | NaT | 0.731832 | NaN | 0.110929 | NaN | 0.430827 |
2 | 2017-10-01 | NaN | 0.243280 | NaN | 0.927472 | NaN |
3 | NaT | NaN | NaN | NaN | NaN | NaN |
4 | 2017-10-01 | NaN | 0.951334 | NaN | 0.620587 | NaN |
5 | NaT | NaN | NaN | NaN | NaN | NaN |
6 | 2017-10-01 | NaN | 0.345831 | NaN | 0.023264 | NaN |
7 | NaT | 0.522263 | NaN | 0.757472 | NaN | 0.072000 |
8 | 2017-10-01 | NaN | 0.928859 | NaN | 0.718561 | NaN |
下面的操作是基于上面的表格来的,不互相影响
可以看到,连续缺失值也是按照前序数值进行填充的,并且完全填充。这里,我们可以通过 limit=
参数设置连续填充的限制数量。
df.fillna(method='pad', limit=1) # 最多填充一项
Time | A | B | C | D | E | |
---|---|---|---|---|---|---|
0 | 2017-10-01 | 0.604915 | 0.205769 | 0.265589 | 0.133621 | 0.348693 |
1 | 2017-10-01 | 0.731832 | 0.205769 | 0.110929 | 0.133621 | 0.430827 |
2 | 2017-10-01 | 0.731832 | 0.243280 | 0.110929 | 0.927472 | 0.430827 |
3 | 2017-10-01 | NaN | 0.243280 | NaN | 0.927472 | NaN |
4 | 2017-10-01 | NaN | 0.951334 | NaN | 0.620587 | NaN |
5 | 2017-10-01 | NaN | 0.951334 | NaN | 0.620587 | NaN |
6 | 2017-10-01 | NaN | 0.345831 | NaN | 0.023264 | NaN |
7 | 2017-10-01 | 0.522263 | 0.345831 | 0.757472 | 0.023264 | 0.072000 |
8 | 2017-10-01 | 0.522263 | 0.928859 | 0.757472 | 0.718561 | 0.072000 |
df.fillna(method='pad')
Time | A | B | C | D | E | |
---|---|---|---|---|---|---|
0 | 2017-10-01 | 0.604915 | 0.205769 | 0.265589 | 0.133621 | 0.348693 |
1 | 2017-10-01 | 0.731832 | 0.205769 | 0.110929 | 0.133621 | 0.430827 |
2 | 2017-10-01 | 0.731832 | 0.243280 | 0.110929 | 0.927472 | 0.430827 |
3 | 2017-10-01 | 0.731832 | 0.243280 | 0.110929 | 0.927472 | 0.430827 |
4 | 2017-10-01 | 0.731832 | 0.951334 | 0.110929 | 0.620587 | 0.430827 |
5 | 2017-10-01 | 0.731832 | 0.951334 | 0.110929 | 0.620587 | 0.430827 |
6 | 2017-10-01 | 0.731832 | 0.345831 | 0.110929 | 0.023264 | 0.430827 |
7 | 2017-10-01 | 0.522263 | 0.345831 | 0.757472 | 0.023264 | 0.072000 |
8 | 2017-10-01 | 0.522263 | 0.928859 | 0.757472 | 0.718561 | 0.072000 |
除了上面的填充方式,还可以通过 Pandas 自带的求平均值方法等来填充特定列或行。举个例子:
df.fillna(df.mean()['C':'E'])