目录

缺少数据基础

何时/为何 数据丢失?

被视为“缺失”的值

日期时间

插入缺失数据

缺少数据的计算

Sum/Prod of Empties/Nans

GroupBy中的NA值

清理/填写缺失数据

填充缺失值:fillna

用PandasObject填充

删除轴标签缺少数据:dropna

插值

插值限制

替换通用值

字符串/正则表达式替换

数字替换

缺少数据转换规则和索引


注意:

NaN内部使用以表示缺失数据的选择主要是出于简单性和性能原因。例如,它与MaskedArray方法不同scikits.timeseries。我们希望NumPy能够很快提供足够的本地NA类型解决方案(类似于R),以便在熊猫中使用。

缺少数据基础

何时/为何 数据丢失?

有些人可能会对我们对失踪的使用进行狡辩。“失踪”只是指 NA(“不可用”)或“因任何原因不存在”。许多数据集只是因缺少数据而到达,因为它存在且未被收集或从未存在过。例如,在财务时间序列的集合中,某些时间序列可能在不同的日期开始。因此,开始日期之前的值通常会被标记为缺失。

在pandas中,将数据丢失引入数据集的最常见方法之一是重新索引。例如:

In [1]: df = pd.DataFrame(np.random.randn(5, 3), index=['a', 'c', 'e', 'f', 'h'],...:                   columns=['one', 'two', 'three'])...: In [2]: df['four'] = 'bar'In [3]: df['five'] = df['one'] > 0In [4]: df
Out[4]: one       two     three four   five
a -0.166778  0.501113 -0.355322  bar  False
c -0.337890  0.580967  0.983801  bar  False
e  0.057802  0.761948 -0.712964  bar   True
f -0.443160 -0.974602  1.047704  bar  False
h -0.717852 -1.053898 -0.019369  bar  FalseIn [5]: df2 = df.reindex(['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'])In [6]: df2
Out[6]: one       two     three four   five
a -0.166778  0.501113 -0.355322  bar  False
b       NaN       NaN       NaN  NaN    NaN
c -0.337890  0.580967  0.983801  bar  False
d       NaN       NaN       NaN  NaN    NaN
e  0.057802  0.761948 -0.712964  bar   True
f -0.443160 -0.974602  1.047704  bar  False
g       NaN       NaN       NaN  NaN    NaN
h -0.717852 -1.053898 -0.019369  bar  False

被视为“缺失”的值

由于数据有许多形状和形式,因此大熊猫的目标是在处理缺失数据时保持灵活性。虽然NaN是计算速度和便利性的默认缺失值标记,但我们需要能够使用不同类型的数据轻松检测此值:浮点,整数,布尔值和一般对象。然而,在许多情况下,Python None会出现,我们也希望考虑“缺失”或“不可用”或“不适用”。

注意:如果你想在计算中考虑inf并且-inf是“NA”,你可以设置。pandas.options.mode.use_inf_as_na = True

为了使检测的缺失值更容易(和不同阵列dtypes),熊猫提供isna()和 notna()功能,这也是对系列的方法和数据帧的对象:

In [7]: df2['one']
Out[7]:
a   -0.166778
b         NaN
c   -0.337890
d         NaN
e    0.057802
f   -0.443160
g         NaN
h   -0.717852
Name: one, dtype: float64In [8]: pd.isna(df2['one'])
Out[8]:
a    False
b     True
c    False
d     True
e    False
f    False
g     True
h    False
Name: one, dtype: boolIn [9]: df2['four'].notna()
Out[9]:
a     True
b    False
c     True
d    False
e     True
f     True
g    False
h     True
Name: four, dtype: boolIn [10]: df2.isna()
Out[10]: one    two  three   four   five
a  False  False  False  False  False
b   True   True   True   True   True
c  False  False  False  False  False
d   True   True   True   True   True
e  False  False  False  False  False
f  False  False  False  False  False
g   True   True   True   True   True
h  False  False  False  False  False

警告

必须要注意的是,在Python(和NumPy)中,nan's不要比较相等,但要None's 做到。请注意,pandas / NumPy使用的事实是,并且像对待一样。np.nan != np.nanNonenp.nan

In [11]: None == None
Out[11]: TrueIn [12]: np.nan == np.nan
Out[12]: False

因此,与上面相比,标量相等比较与a None/np.nan不提供有用的信息。

In [13]: df2['one'] == np.nan
Out[13]:
a    False
b    False
c    False
d    False
e    False
f    False
g    False
h    False
Name: one, dtype: bool

日期时间

对于datetime64 [ns]类型,NaT表示缺少的值。这是一个伪本机标记值,可以由单个dtype(datetime64 [ns])中的NumPy表示。pandas对象提供NaT和之间的互操作性NaN

In [14]: df2 = df.copy()In [15]: df2['timestamp'] = pd.Timestamp('20120101')In [16]: df2
Out[16]: one       two     three four   five  timestamp
a -0.166778  0.501113 -0.355322  bar  False 2012-01-01
c -0.337890  0.580967  0.983801  bar  False 2012-01-01
e  0.057802  0.761948 -0.712964  bar   True 2012-01-01
f -0.443160 -0.974602  1.047704  bar  False 2012-01-01
h -0.717852 -1.053898 -0.019369  bar  False 2012-01-01In [17]: df2.loc[['a','c','h'],['one','timestamp']] = np.nanIn [18]: df2
Out[18]: one       two     three four   five  timestamp
a       NaN  0.501113 -0.355322  bar  False        NaT
c       NaN  0.580967  0.983801  bar  False        NaT
e  0.057802  0.761948 -0.712964  bar   True 2012-01-01
f -0.443160 -0.974602  1.047704  bar  False 2012-01-01
h       NaN -1.053898 -0.019369  bar  False        NaTIn [19]: df2.get_dtype_counts()
Out[19]:
float64           3
object            1
bool              1
datetime64[ns]    1
dtype: int64

插入缺失数据

您只需分配容器即可插入缺失值。使用的实际缺失值将根据dtype选择。

例如,NaN无论选择的缺失值类型如何,数字容器将始终使用:

In [20]: s = pd.Series([1, 2, 3])In [21]: s.loc[0] = NoneIn [22]: s
Out[22]:
0    NaN
1    2.0
2    3.0
dtype: float64

同样,datetime容器将始终使用NaT

对于对象容器,pandas将使用给定的值:

In [23]: s = pd.Series(["a", "b", "c"])In [24]: s.loc[0] = NoneIn [25]: s.loc[1] = np.nanIn [26]: s
Out[26]:
0    None
1     NaN
2       c
dtype: object

缺少数据的计算

缺失值通过pandas对象之间的算术运算自然传播。

In [27]: a
Out[27]: one       two
a       NaN  0.501113
c       NaN  0.580967
e  0.057802  0.761948
f -0.443160 -0.974602
h -0.443160 -1.053898In [28]: b
Out[28]: one       two     three
a       NaN  0.501113 -0.355322
c       NaN  0.580967  0.983801
e  0.057802  0.761948 -0.712964
f -0.443160 -0.974602  1.047704
h       NaN -1.053898 -0.019369In [29]: a + b
Out[29]: one  three       two
a       NaN    NaN  1.002226
c       NaN    NaN  1.161935
e  0.115604    NaN  1.523896
f -0.886321    NaN -1.949205
h       NaN    NaN -2.107796

数据结构概述(以及此处和此处列出)中讨论的描述性统计和计算方法 都是为了解决丢失的数据而编写的。例如:

  • 求和数据时,NA(缺失)值将被视为零。
  • 如果数据都是NA,则结果为0。
  • 默认情况下,累积方法cumsum()cumprod()忽略NA值,但在结果数组中保留它们。要覆盖此行为并包含NA值,请使用skipna=False
In [30]: df
Out[30]: one       two     three
a       NaN  0.501113 -0.355322
c       NaN  0.580967  0.983801
e  0.057802  0.761948 -0.712964
f -0.443160 -0.974602  1.047704
h       NaN -1.053898 -0.019369In [31]: df['one'].sum()
Out[31]: -0.38535826528461409In [32]: df.mean(1)
Out[32]:
a    0.072895
c    0.782384
e    0.035595
f   -0.123353
h   -0.536633
dtype: float64In [33]: df.cumsum()
Out[33]: one       two     three
a       NaN  0.501113 -0.355322
c       NaN  1.082080  0.628479
e  0.057802  1.844028 -0.084485
f -0.385358  0.869426  0.963219
h       NaN -0.184472  0.943850In [34]: df.cumsum(skipna=False)
Out[34]: one       two     three
a  NaN  0.501113 -0.355322
c  NaN  1.082080  0.628479
e  NaN  1.844028 -0.084485
f  NaN  0.869426  0.963219
h  NaN -0.184472  0.943850

Sum/Prod of Empties/Nans

警告

此行为现​​在是v0.22.0的标准,并且与默认值一致numpy; 之前所有NA或空系列/数据框的sum / prod将返回NaN。有关更多信息,请参阅v0.22.0 whatsnew。

DataFrame的空或全NA系列或列的总和为0。

In [35]: pd.Series([np.nan]).sum()
Out[35]: 0.0In [36]: pd.Series([]).sum()
Out[36]: 0.0

空数据或全NA系列或DataFrame列的乘积为1。

In [37]: pd.Series([np.nan]).prod()
Out[37]: 1.0In [38]: pd.Series([]).prod()
Out[38]: 1.0

GroupBy中的NA值

GroupBy中的NA组被自动排除。此行为与R一致,例如:

In [39]: df
Out[39]: one       two     three
a       NaN  0.501113 -0.355322
c       NaN  0.580967  0.983801
e  0.057802  0.761948 -0.712964
f -0.443160 -0.974602  1.047704
h       NaN -1.053898 -0.019369In [40]: df.groupby('one').mean()
Out[40]: two     three
one
-0.443160 -0.974602  1.0477040.057802  0.761948 -0.712964

有关详细信息,请参阅此处的groupby部分。

清理/填写缺失数据

pandas对象配备有各种数据处理方法来处理丢失的数据。

填充缺失值:fillna

fillna() 可以通过几种方式用非NA数据“填写”NA值,我们将说明:

用标量值替换NA

In [41]: df2
Out[41]: one       two     three four   five  timestamp
a       NaN  0.501113 -0.355322  bar  False        NaT
c       NaN  0.580967  0.983801  bar  False        NaT
e  0.057802  0.761948 -0.712964  bar   True 2012-01-01
f -0.443160 -0.974602  1.047704  bar  False 2012-01-01
h       NaN -1.053898 -0.019369  bar  False        NaTIn [42]: df2.fillna(0)
Out[42]: one       two     three four   five            timestamp
a  0.000000  0.501113 -0.355322  bar  False                    0
c  0.000000  0.580967  0.983801  bar  False                    0
e  0.057802  0.761948 -0.712964  bar   True  2012-01-01 00:00:00
f -0.443160 -0.974602  1.047704  bar  False  2012-01-01 00:00:00
h  0.000000 -1.053898 -0.019369  bar  False                    0In [43]: df2['one'].fillna('missing')
Out[43]:
a     missing
c     missing
e    0.057802
f    -0.44316
h     missing
Name: one, dtype: object

向前或向后填补空隙

使用与重建索引相同的填充参数,我们可以向前或向后传播非NA值:

In [44]: df
Out[44]: one       two     three
a       NaN  0.501113 -0.355322
c       NaN  0.580967  0.983801
e  0.057802  0.761948 -0.712964
f -0.443160 -0.974602  1.047704
h       NaN -1.053898 -0.019369In [45]: df.fillna(method='pad')
Out[45]: one       two     three
a       NaN  0.501113 -0.355322
c       NaN  0.580967  0.983801
e  0.057802  0.761948 -0.712964
f -0.443160 -0.974602  1.047704
h -0.443160 -1.053898 -0.019369

限制填充量

如果我们只想要填充一定数量的数据点的连续间隙,我们可以使用limit关键字:

In [46]: df
Out[46]: one       two     three
a  NaN  0.501113 -0.355322
c  NaN  0.580967  0.983801
e  NaN       NaN       NaN
f  NaN       NaN       NaN
h  NaN -1.053898 -0.019369In [47]: df.fillna(method='pad', limit=1)
Out[47]: one       two     three
a  NaN  0.501113 -0.355322
c  NaN  0.580967  0.983801
e  NaN  0.580967  0.983801
f  NaN       NaN       NaN
h  NaN -1.053898 -0.019369

提醒您,这些是可用的填充方法:

方法 行动
垫/ ffill 向前填充值
bfill /回填 向后填充值

对于时间序列数据,使用pad / ffill非常常见,因此在每个时间点都可以使用“最后已知值”。

ffill()相当于fillna(method='ffill') 和bfill()等同于fillna(method='bfill')

用PandasObject填充

您还可以使用可对齐的字典或系列填充。系列的字典或索引的标签必须与您要填充的框架的列相匹配。其用例是使用该列的平均值填充DataFrame。

In [48]: dff = pd.DataFrame(np.random.randn(10,3), columns=list('ABC'))In [49]: dff.iloc[3:5,0] = np.nanIn [50]: dff.iloc[4:6,1] = np.nanIn [51]: dff.iloc[5:8,2] = np.nanIn [52]: dff
Out[52]: A         B         C
0  0.758887  2.340598  0.219039
1 -1.235583  0.031785  0.701683
2 -1.557016 -0.636986 -1.238610
3       NaN -1.002278  0.654052
4       NaN       NaN  1.053999
5  0.651981       NaN       NaN
6  0.109001 -0.533294       NaN
7 -1.037831 -1.150016       NaN
8 -0.687693  1.921056 -0.121113
9 -0.258742 -0.706329  0.402547In [53]: dff.fillna(dff.mean())
Out[53]: A         B         C
0  0.758887  2.340598  0.219039
1 -1.235583  0.031785  0.701683
2 -1.557016 -0.636986 -1.238610
3 -0.407125 -1.002278  0.654052
4 -0.407125  0.033067  1.053999
5  0.651981  0.033067  0.238800
6  0.109001 -0.533294  0.238800
7 -1.037831 -1.150016  0.238800
8 -0.687693  1.921056 -0.121113
9 -0.258742 -0.706329  0.402547In [54]: dff.fillna(dff.mean()['B':'C'])
Out[54]: A         B         C
0  0.758887  2.340598  0.219039
1 -1.235583  0.031785  0.701683
2 -1.557016 -0.636986 -1.238610
3       NaN -1.002278  0.654052
4       NaN  0.033067  1.053999
5  0.651981  0.033067  0.238800
6  0.109001 -0.533294  0.238800
7 -1.037831 -1.150016  0.238800
8 -0.687693  1.921056 -0.121113
9 -0.258742 -0.706329  0.402547

与上面的结果相同,但是在这种情况下对齐'fill'值是一个系列。

In [55]: dff.where(pd.notna(dff), dff.mean(), axis='columns')
Out[55]: A         B         C
0  0.758887  2.340598  0.219039
1 -1.235583  0.031785  0.701683
2 -1.557016 -0.636986 -1.238610
3 -0.407125 -1.002278  0.654052
4 -0.407125  0.033067  1.053999
5  0.651981  0.033067  0.238800
6  0.109001 -0.533294  0.238800
7 -1.037831 -1.150016  0.238800
8 -0.687693  1.921056 -0.121113
9 -0.258742 -0.706329  0.402547

删除轴标签缺少数据:dropna

您可能希望简单地从引用缺失数据的数据集中排除标签。为此,请使用dropna()

In [56]: df
Out[56]: one       two     three
a  NaN  0.501113 -0.355322
c  NaN  0.580967  0.983801
e  NaN  0.000000  0.000000
f  NaN  0.000000  0.000000
h  NaN -1.053898 -0.019369In [57]: df.dropna(axis=0)
Out[57]:
Empty DataFrame
Columns: [one, two, three]
Index: []In [58]: df.dropna(axis=1)
Out[58]: two     three
a  0.501113 -0.355322
c  0.580967  0.983801
e  0.000000  0.000000
f  0.000000  0.000000
h -1.053898 -0.019369In [59]: df['one'].dropna()
Out[59]: Series([], Name: one, dtype: float64)

dropna()系列可以使用等效产品。DataFrame.dropna具有比Series.dropna更多的选项,可以在API中进行检查。

插值

在0.21.0版本中的新limit_area加入关键字参数。

interpolate() 默认情况下,Series和DataFrame对象都会在缺少的数据点处执行线性插值。

In [60]: ts
Out[60]:
2000-01-31    0.469112
2000-02-29         NaN
2000-03-31         NaN
2000-04-28         NaN
2000-05-31         NaN
2000-06-30         NaN
2000-07-31         NaN...
2007-10-31   -3.305259
2007-11-30   -5.485119
2007-12-31   -6.854968
2008-01-31   -7.809176
2008-02-29   -6.346480
2008-03-31   -8.089641
2008-04-30   -8.916232
Freq: BM, Length: 100, dtype: float64In [61]: ts.count()
Out[61]: 61In [62]: ts.interpolate().count()
Out[62]: 100In [63]: ts.interpolate().plot()
Out[63]: <matplotlib.axes._subplots.AxesSubplot at 0x7f20cf59ca58>

通过method关键字可以获得索引感知插值:

In [64]: ts2
Out[64]:
2000-01-31    0.469112
2000-02-29         NaN
2002-07-31   -5.689738
2005-01-31         NaN
2008-04-30   -8.916232
dtype: float64In [65]: ts2.interpolate()
Out[65]:
2000-01-31    0.469112
2000-02-29   -2.610313
2002-07-31   -5.689738
2005-01-31   -7.302985
2008-04-30   -8.916232
dtype: float64In [66]: ts2.interpolate(method='time')
Out[66]:
2000-01-31    0.469112
2000-02-29    0.273272
2002-07-31   -5.689738
2005-01-31   -7.095568
2008-04-30   -8.916232
dtype: float64

对于浮点索引,请使用method='values'

In [67]: ser
Out[67]:
0.0      0.0
1.0      NaN
10.0    10.0
dtype: float64In [68]: ser.interpolate()
Out[68]:
0.0      0.0
1.0      5.0
10.0    10.0
dtype: float64In [69]: ser.interpolate(method='values')
Out[69]:
0.0      0.0
1.0      1.0
10.0    10.0
dtype: float64

您还可以使用DataFrame进行插值:

In [70]: df = pd.DataFrame({'A': [1, 2.1, np.nan, 4.7, 5.6, 6.8],....:                    'B': [.25, np.nan, np.nan, 4, 12.2, 14.4]})....: In [71]: df
Out[71]: A      B
0  1.0   0.25
1  2.1    NaN
2  NaN    NaN
3  4.7   4.00
4  5.6  12.20
5  6.8  14.40In [72]: df.interpolate()
Out[72]: A      B
0  1.0   0.25
1  2.1   1.50
2  3.4   2.75
3  4.7   4.00
4  5.6  12.20
5  6.8  14.40

method参数提供了对更高级插值方法的访问。如果安装了scipy,则可以将1-d插值例程的名称传递给method。您需要查阅完整的scipy插值文档和参考指南以获取详细信息。适当的插值方法取决于您使用的数据类型。

  • 如果您正在处理以不断增长的速度增长的时间序列,则 method='quadratic'可能是合适的。
  • 如果您的值接近累积分布函数,那么method='pchip'应该可以正常工作。
  • 要以平滑绘图的目标填充缺失值,请考虑method='akima'

警告:这些方法需要scipy

In [73]: df.interpolate(method='barycentric')
Out[73]: A       B
0  1.00   0.250
1  2.10  -7.660
2  3.53  -4.515
3  4.70   4.000
4  5.60  12.200
5  6.80  14.400In [74]: df.interpolate(method='pchip')
Out[74]: A          B
0  1.00000   0.250000
1  2.10000   0.672808
2  3.43454   1.928950
3  4.70000   4.000000
4  5.60000  12.200000
5  6.80000  14.400000In [75]: df.interpolate(method='akima')
Out[75]: A          B
0  1.000000   0.250000
1  2.100000  -0.873316
2  3.406667   0.320034
3  4.700000   4.000000
4  5.600000  12.200000
5  6.800000  14.400000

通过多项式或样条逼近进行插值时,还必须指定近似的度数或阶数:

In [76]: df.interpolate(method='spline', order=2)
Out[76]: A          B
0  1.000000   0.250000
1  2.100000  -0.428598
2  3.404545   1.206900
3  4.700000   4.000000
4  5.600000  12.200000
5  6.800000  14.400000In [77]: df.interpolate(method='polynomial', order=2)
Out[77]: A          B
0  1.000000   0.250000
1  2.100000  -2.703846
2  3.451351  -1.453846
3  4.700000   4.000000
4  5.600000  12.200000
5  6.800000  14.400000

比较几种方法:

In [78]: np.random.seed(2)In [79]: ser = pd.Series(np.arange(1, 10.1, .25)**2 + np.random.randn(37))In [80]: bad = np.array([4, 13, 14, 15, 16, 17, 18, 20, 29])In [81]: ser[bad] = np.nanIn [82]: methods = ['linear', 'quadratic', 'cubic']In [83]: df = pd.DataFrame({m: ser.interpolate(method=m) for m in methods})In [84]: df.plot()
Out[84]: <matplotlib.axes._subplots.AxesSubplot at 0x7f20cf573fd0>

另一个用例是以值插值。假设您有一些分布的100个观察值。让我们假设你对中间发生的事情特别感兴趣。您可以混合使用pandas reindexinterpolate方法来插入新值。

In [85]: ser = pd.Series(np.sort(np.random.uniform(size=100)))# interpolate at new_index
In [86]: new_index = ser.index | pd.Index([49.25, 49.5, 49.75, 50.25, 50.5, 50.75])In [87]: interp_s = ser.reindex(new_index).interpolate(method='pchip')In [88]: interp_s[49:51]
Out[88]:
49.00    0.471410
49.25    0.476841
49.50    0.481780
49.75    0.485998
50.00    0.489266
50.25    0.491814
50.50    0.493995
50.75    0.495763
51.00    0.497074
dtype: float64

插值限制

像其他pandas fill方法一样,interpolate()接受limit关键字参数。使用此参数可限制NaN自上次有效观察以来填充的连续值的数量:

In [89]: ser = pd.Series([np.nan, np.nan, 5, np.nan, np.nan, np.nan, 13, np.nan, np.nan])# fill all consecutive values in a forward direction
In [90]: ser.interpolate()
Out[90]:
0     NaN
1     NaN
2     5.0
3     7.0
4     9.0
5    11.0
6    13.0
7    13.0
8    13.0
dtype: float64# fill one consecutive value in a forward direction
In [91]: ser.interpolate(limit=1)
Out[91]:
0     NaN
1     NaN
2     5.0
3     7.0
4     NaN
5     NaN
6    13.0
7    13.0
8     NaN
dtype: float64

默认情况下,NaN值按forward方向填充。使用 limit_direction参数填充backward或从both方向填充。

# fill one consecutive value backwards
In [92]: ser.interpolate(limit=1, limit_direction='backward')
Out[92]:
0     NaN
1     5.0
2     5.0
3     NaN
4     NaN
5    11.0
6    13.0
7     NaN
8     NaN
dtype: float64# fill one consecutive value in both directions
In [93]: ser.interpolate(limit=1, limit_direction='both')
Out[93]:
0     NaN
1     5.0
2     5.0
3     7.0
4     NaN
5    11.0
6    13.0
7    13.0
8     NaN
dtype: float64# fill all consecutive values in both directions
In [94]: ser.interpolate(limit_direction='both')
Out[94]:
0     5.0
1     5.0
2     5.0
3     7.0
4     9.0
5    11.0
6    13.0
7    13.0
8    13.0
dtype: float64

默认情况下,NaN无论值是在现有有效值内部(由其包围)还是在现有有效值之外,都会填充值。在v0.23中引入的limit_area参数将填充限制为内部或外部值。

# fill one consecutive inside value in both directions
In [95]: ser.interpolate(limit_direction='both', limit_area='inside', limit=1)
Out[95]:
0     NaN
1     NaN
2     5.0
3     7.0
4     NaN
5    11.0
6    13.0
7     NaN
8     NaN
dtype: float64# fill all consecutive outside values backward
In [96]: ser.interpolate(limit_direction='backward', limit_area='outside')
Out[96]:
0     5.0
1     5.0
2     5.0
3     NaN
4     NaN
5     NaN
6    13.0
7     NaN
8     NaN
dtype: float64# fill all consecutive outside values in both directions
In [97]: ser.interpolate(limit_direction='both', limit_area='outside')
Out[97]:
0     5.0
1     5.0
2     5.0
3     NaN
4     NaN
5     NaN
6    13.0
7    13.0
8    13.0
dtype: float64

替换通用值

通常我们想用其他值替换任意值。

replace()在Series和replace()DataFrame中提供了一种有效而灵活的方式来执行此类替换。

对于Series,您可以用其他值替换单个值或值列表:

In [98]: ser = pd.Series([0., 1., 2., 3., 4.])In [99]: ser.replace(0, 5)
Out[99]:
0    5.0
1    1.0
2    2.0
3    3.0
4    4.0
dtype: float64

您可以通过其他值列表替换值列表:

In [100]: ser.replace([0, 1, 2, 3, 4], [4, 3, 2, 1, 0])
Out[100]:
0    4.0
1    3.0
2    2.0
3    1.0
4    0.0
dtype: float64

您还可以指定映射字典:

In [101]: ser.replace({0: 10, 1: 100})
Out[101]:
0     10.0
1    100.0
2      2.0
3      3.0
4      4.0
dtype: float64

对于DataFrame,您可以按列指定单个值:

In [102]: df = pd.DataFrame({'a': [0, 1, 2, 3, 4], 'b': [5, 6, 7, 8, 9]})In [103]: df.replace({'a': 0, 'b': 5}, 100)
Out[103]: a    b
0  100  100
1    1    6
2    2    7
3    3    8
4    4    9

您可以将所有给定值视为缺失值并对其进行插值,而不是使用指定值替换:

In [104]: ser.replace([1, 2, 3], method='pad')
Out[104]:
0    0.0
1    0.0
2    0.0
3    0.0
4    4.0
dtype: float64

字符串/正则表达式替换

注意:带有前缀r字符的Python字符串,例如 所谓的“原始”字符串。它们具有与反斜杠不同的语义,而不是没有此前缀的字符串。原始字符串中的反斜杠将被解释为转义反斜杠,例如。 如果不清楚,你应该阅读它们。r'helloworld'r'\' == '\\'

更换 '。' 用NaN(str - > str):

In [105]: d = {'a': list(range(4)), 'b': list('ab..'), 'c': ['a', 'b', np.nan, 'd']}In [106]: df = pd.DataFrame(d)In [107]: df.replace('.', np.nan)
Out[107]: a    b    c
0  0    a    a
1  1    b    b
2  2  NaN  NaN
3  3  NaN    d

现在使用正则表达式删除周围的空格(正则表达式 - >正则表达式):

In [108]: df.replace(r'\s*\.\s*', np.nan, regex=True)
Out[108]: a    b    c
0  0    a    a
1  1    b    b
2  2  NaN  NaN
3  3  NaN    d

替换几个不同的值(列表 - >列表):

In [109]: df.replace(['a', '.'], ['b', np.nan])
Out[109]: a    b    c
0  0    b    b
1  1    b    b
2  2  NaN  NaN
3  3  NaN    d

正则表达式列表 - >正则表达式列表:

In [110]: df.replace([r'\.', r'(a)'], ['dot', '\1stuff'], regex=True)
Out[110]: a       b       c
0  0  stuff  stuff
1  1       b       b
2  2     dot     NaN
3  3     dot       d

只搜索列'b'(dict - > dict):

In [111]: df.replace({'b': '.'}, {'b': np.nan})
Out[111]: a    b    c
0  0    a    a
1  1    b    b
2  2  NaN  NaN
3  3  NaN    d

与前一个示例相同,但使用正则表达式进行搜索(dge of regex - > dict):

In [112]: df.replace({'b': r'\s*\.\s*'}, {'b': np.nan}, regex=True)
Out[112]: a    b    c
0  0    a    a
1  1    b    b
2  2  NaN  NaN
3  3  NaN    d

您可以传递使用regex=True以下内容的正则表达式的嵌套字典:

In [113]: df.replace({'b': {'b': r''}}, regex=True)
Out[113]: a  b    c
0  0  a    a
1  1       b
2  2  .  NaN
3  3  .    d

或者,您可以像这样传递嵌套字典:

In [114]: df.replace(regex={'b': {r'\s*\.\s*': np.nan}})
Out[114]: a    b    c
0  0    a    a
1  1    b    b
2  2  NaN  NaN
3  3  NaN    d

您还可以在替换时使用正则表达式匹配组(正则表达式 - >正则表达式的dict),这也适用于列表。

In [115]: df.replace({'b': r'\s*(\.)\s*'}, {'b': r'\1ty'}, regex=True)
Out[115]: a    b    c
0  0    a    a
1  1    b    b
2  2  .ty  NaN
3  3  .ty    d

您可以传递正则表达式列表,其中匹配的正则表达式将替换为标量(正则表达式列表 - >正则表达式)。

In [116]: df.replace([r'\s*\.\s*', r'a|b'], np.nan, regex=True)
Out[116]: a   b    c
0  0 NaN  NaN
1  1 NaN  NaN
2  2 NaN  NaN
3  3 NaN    d

所有正则表达式示例也可以以to_replace参数作为regex参数传递 。在这种情况下,value 参数必须通过名称显式传递,或者regex必须是嵌套字典。在这种情况下,前一个示例将是:

In [117]: df.replace(regex=[r'\s*\.\s*', r'a|b'], value=np.nan)
Out[117]: a   b    c
0  0 NaN  NaN
1  1 NaN  NaN
2  2 NaN  NaN
3  3 NaN    d

如果您不希望regex=True每次要使用正则表达式时都这样做,这将非常方便。

注意:在上面的replace示例中,您看到正则表达式的任何位置,编译的正则表达式也是有效的。

数字替换

replace()类似于fillna()

In [118]: df = pd.DataFrame(np.random.randn(10, 2))In [119]: df[np.random.rand(df.shape[0]) > 0.5] = 1.5In [120]: df.replace(1.5, np.nan)
Out[120]: 0         1
0 -0.844214 -1.021415
1  0.432396 -0.323580
2  0.423825  0.799180
3  1.262614  0.751965
4       NaN       NaN
5       NaN       NaN
6 -0.498174 -1.060799
7  0.591667 -0.183257
8  1.019855 -1.482465
9       NaN       NaN

通过传递列表可以替换多个值。

In [121]: df00 = df.values[0, 0]In [122]: df.replace([1.5, df00], [np.nan, 'a'])
Out[122]: 0         1
0         a  -1.02141
1  0.432396  -0.32358
2  0.423825   0.79918
3   1.26261  0.751965
4       NaN       NaN
5       NaN       NaN
6 -0.498174   -1.0608
7  0.591667 -0.183257
8   1.01985  -1.48247
9       NaN       NaNIn [123]: df[1].dtype
Out[123]: dtype('float64')

您还可以对DataFrame进行操作:

In [124]: df.replace(1.5, np.nan, inplace=True)

警告

替换多个booldatetime64对象时,replaceto_replace)的第一个参数必须与要替换的值的类型匹配。例如,

s = pd.Series([True, False, True])
s.replace({'a string': 'new value', True: False})  # raisesTypeError: Cannot compare types 'ndarray(dtype=bool)' and 'str'

会引发一个,TypeError因为其中一个dict键的更换类型不正确。

但是,当替换单个对象时,

In [125]: s = pd.Series([True, False, True])In [126]: s.replace('a string', 'another string')
Out[126]:
0     True
1    False
2     True
dtype: bool

原始NDFrame对象将不会被返回。我们正在努力统一此API,但出于向后兼容性原因,我们无法打破后一种行为。有关详细信息,请参见GH6354。

缺少数据转换规则和索引

虽然pandas支持存储整数和布尔类型的数组,但这些类型不能存储丢失的数据。在我们可以切换到在NumPy中使用本机NA类型之前,我们已经建立了一些“投射规则”。当重建索引操作引入缺失数据时,系列将根据下表中引入的规则进行转换。

数据类型 演员
整数 浮动
布尔 目的
浮动 没有演员
目的 没有演员

例如:

In [127]: s = pd.Series(np.random.randn(5), index=[0, 2, 4, 6, 7])In [128]: s > 0
Out[128]:
0    True
2    True
4    True
6    True
7    True
dtype: boolIn [129]: (s > 0).dtype
Out[129]: dtype('bool')In [130]: crit = (s > 0).reindex(list(range(8)))In [131]: crit
Out[131]:
0    True
1     NaN
2    True
3     NaN
4    True
5     NaN
6    True
7    True
dtype: objectIn [132]: crit.dtype
Out[132]: dtype('O')

通常,如果您尝试使用对象数组(即使它包含布尔值)而不是布尔数组来从ndarray获取或设置值(例如,根据某些条件选择值),NumPy会抱怨。如果布尔向量包含NA,则会生成异常:

In [133]: reindexed = s.reindex(list(range(8))).fillna(0)In [134]: reindexed[crit]
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-134-0dac417a4890> in <module>()
----> 1 reindexed[crit]/pandas/pandas/core/series.py in __getitem__(self, key)805             key = list(key)806
--> 807         if com.is_bool_indexer(key):808             key = check_bool_indexer(self.index, key)809 /pandas/pandas/core/common.py in is_bool_indexer(key)105             if not lib.is_bool_array(key):106                 if isna(key).any():
--> 107                     raise ValueError('cannot index with vector containing '108                                      'NA / NaN values')109                 return FalseValueError: cannot index with vector containing NA / NaN values

但是,这些可以填写使用fillna(),它将工作正常:

In [135]: reindexed[crit.fillna(False)]
Out[135]:
0    0.126504
2    0.696198
4    0.697416
6    0.601516
7    0.003659
dtype: float64In [136]: reindexed[crit.fillna(True)]
Out[136]:
0    0.126504
1    0.000000
2    0.696198
3    0.000000
4    0.697416
5    0.000000
6    0.601516
7    0.003659
dtype: float64

【数据预处理】Pandas缺失的数据处理相关推荐

  1. 数据预处理之数据合并(基于pandas)

    文章目录 数据预处理 pandas.concat pandas.DateFrame.append pandas.merge pandas.DateFrame.join 数据预处理 数据预处理主要包括: ...

  2. 【R】【课程笔记】04+05 数据预处理+收益率计算

    本文是课程<数据科学与金融计算>第4-5章的学习笔记,主要介绍金融数据处理.收益率计算和R与C++调用,用于知识点总结和代码练习,Q&A为问题及解决方案. 往期回顾: 博文 内容 ...

  3. pandas数据预处理(标准化归一化、离散化/分箱/分桶、分类数据处理、时间类型数据处理、样本类别分布不均衡数据处理、数据抽样)

    1. 数值型数据的处理 1.1 标准化&归一化 数据标准化是一个常用的数据预处理操作,目的是处理不同规模和量纲的数据,使其缩放到相同的数据区间和范围,以减少规模.特征.分布差异等对模型的影响. ...

  4. 数据分析之Pandas缺失数据处理

    ↑↑↑关注后"星标"Datawhale每日干货 & 每月组队学习,不错过Datawhale干货 作者:耿远昊,Datawhale成员,华东师范大学Pandas 是一个强大的 ...

  5. 插值法补齐缺失数据_数据挖掘非常重要的一步:数据预处理

    为什么数据处理很重要? 对数据挖掘熟悉的小伙伴,数据处理相关的工作时间占据了整个项目的70%以上.数据的质量,直接决定了模型的预测和泛化能力的好坏.它涉及很多因素,包括:准确性.完整性.一致性.时效性 ...

  6. 【Pandas】一文入门Pandas处理csv文件数据集(神经网络/机器学习算法数据预处理)

    Motivation 和某个大佬采集的数据是csv格式的,之前没处理过csv格式的数据.拿来写神经网络训练的时候踩了不少坑,这里记录一下,也方便后来人学习. Pandas处理csv文件 处理csv文件 ...

  7. Pandas 数据预处理

    Pandas数据处理 一 概述 1.1 业务建模流程 将业务抽象为分类or回归问题 定义标签,得到y 选取合适的样本,并匹配出全部的信息作为特征的来源 特征工程 + 模型训练 + 模型评价与调优(相互 ...

  8. python数据处理实例-Python数据预处理实例详解

    Python----数据预处理代码实例 本文实例为大家分享了Python数据预处理的具体代码,供大家参考,具体内容如下 1.导入标准库 import numpy as np import matplo ...

  9. Pandas简明教程:七、Pandas缺失数据的处理(数据清洗基础)

    文章目录 1.缺失数据的类型 2.定位缺失数据 3.修改定位数据 4.批量修改缺失数据 5.数据修复的利器--插值法(`interpolate`) 本系列教程教程完整目录: 数据清洗的内容其实很丰富, ...

最新文章

  1. Java基础知识强化之IO流笔记41:字符流缓冲流之复制文本文件案例02(使用 [ newLine() / readLine() ] )(重要)...
  2. python专科找工作难吗-本人小白,想学python,大专不知道好不好找工作?
  3. 成功解决AttributeError: ‘JointGrid‘ object has no attribute ‘annotate‘
  4. 支持回调处理 php函数,PHP支持回调的函数有哪些
  5. 【学亮IT手记】AngularJS增删改查服务请求+代码剥离封装抽取示例
  6. 使用Spring Security,Thymeleaf和Okta保护Java应用程序的安全
  7. python面试题总结(1)--语言特性
  8. 选择排序、冒泡排序、异或运算
  9. java tcp 线程_java 网络协议(一)Tcp多线程服务器端编程
  10. 《剑指offer》第二十八题(对称的二叉树)
  11. 做测试开发半年涨薪20W入职名企大厂,这位90后凭什么?
  12. 2011-寒假 linux 学习笔记
  13. 福利福利!20行代码教大家抓取斗鱼美女主播封面
  14. 【07月19日】指数估值排名
  15. 【歪门邪道】懒得麻烦UI同学切图所以用AndroidStudio生成icon
  16. 特技替身拜拜,迪士尼机器超人要上天了!
  17. python压缩_Python札记 -- 文件压缩
  18. 41-fcntl设置文件锁
  19. modern android5.1,Modern摩登印app下载-Modern摩登印安卓版下载 v1.1.5_5577安卓网
  20. Windows系统共享文件夹或打印机等设备的dos脚本自动化

热门文章

  1. 弹弹堂 网页游戏 单机自玩 搭建教程
  2. 深入理解金融交易报文Iso8583协议
  3. MySQL字段名获取
  4. 高精度1------高精度乘法
  5. SpringBoot整合Drools
  6. 全球最贵域名Sex.com将再度出售
  7. 2020年 Top 6+ 最佳免费字体网站
  8. 20个创意的产品包装设计
  9. mysql的dba是什么_mysql dba是什么意思?
  10. SNMP MIB库的介绍