处理缺失数据# 被视为“缺失”的值# pandas 根据数据类型使用不同的哨兵值来表示缺失(也称为 NA)。 numpy.nan对于 NumPy 数据类型。使用 NumPy 数据类型的缺点是原始数据类型将被强制为np.float64or object。 In [1]: pd.Series([1, 2], dtype=np.int64).reindex([0, 1, 2]) Out[1]: 0 1.0 1 2.0 2 NaN dtype: float64 In [2]: pd.Series([True, False], dtype=np.bool_).reindex([0, 1, 2]) Out[2]: 0 True 1 False 2 NaN dtype: object NaT对于 NumPy np.datetime64、np.timedelta64和PeriodDtype.对于打字应用程序,请使用api.types.NaTType. In [3]: pd.Series([1, 2], dtype=np.dtype("timedelta64[ns]")).reindex([0, 1, 2]) Out[3]: 0 0 days 00:00:00.000000001 1 0 days 00:00:00.000000002 2 NaT dtype: timedelta64[ns] In [4]: pd.Series([1, 2], dtype=np.dtype("datetime64[ns]")).reindex([0, 1, 2]) Out[4]: 0 1970-01-01 00:00:00.000000001 1 1970-01-01 00:00:00.000000002 2 NaT dtype: datetime64[ns] In [5]: pd.Series(["2020", "2020"], dtype=pd.PeriodDtype("D")).reindex([0, 1, 2]) Out[5]: 0 2020-01-01 1 2020-01-01 2 NaT dtype: period[D] NA对于StringDtype, Int64Dtype(和其他位宽) 和.这些类型将保持数据的原始数据类型。对于打字应用程序,请使用.Float64Dtype`(and other bit widths), :class:`BooleanDtypeArrowDtypeapi.types.NAType In [6]: pd.Series([1, 2], dtype="Int64").reindex([0, 1, 2]) Out[6]: 0 1 1 2 2 <NA> dtype: Int64 In [7]: pd.Series([True, False], dtype="boolean[pyarrow]").reindex([0, 1, 2]) Out[7]: 0 True 1 False 2 <NA> dtype: bool[pyarrow] 要检测这些缺失值,请使用isna()或notna()方法。 In [8]: ser = pd.Series([pd.Timestamp("2020-01-01"), pd.NaT]) In [9]: ser Out[9]: 0 2020-01-01 1 NaT dtype: datetime64[ns] In [10]: pd.isna(ser) Out[10]: 0 False 1 True dtype: bool 笔记 isna()或者notna()也会考虑None缺失值。 In [11]: ser = pd.Series([1, None], dtype=object) In [12]: ser Out[12]: 0 1 1 None dtype: object In [13]: pd.isna(ser) Out[13]: 0 False 1 True dtype: bool 警告 np.nan、NaT、 和之间的相等比较NA 并不像None In [14]: None == None # noqa: E711 Out[14]: True In [15]: np.nan == np.nan Out[15]: False In [16]: pd.NaT == pd.NaT Out[16]: False In [17]: pd.NA == pd.NA Out[17]: <NA> DataFrame因此, a或与这些缺失值之一之间的相等比较Series 不会提供与 isna()或相同的信息notna()。 In [18]: ser = pd.Series([True, None], dtype="boolean[pyarrow]") In [19]: ser == pd.NA Out[19]: 0 <NA> 1 <NA> dtype: bool[pyarrow] In [20]: pd.isna(ser) Out[20]: 0 False 1 True dtype: bool NA语义# 警告 实验性: 的行为NA`仍然可以在没有警告的情况下发生变化。 从pandas 1.0开始,NA可以使用实验值(单例)来表示标量缺失值。的目标NA是提供一个可以跨数据类型一致使用的“缺失”指示符(而不是np.nan,None或pd.NaT取决于数据类型)。 例如,当 a 中存在Series可为空整数数据类型的缺失值时,它将使用NA: In [21]: s = pd.Series([1, 2, None], dtype="Int64") In [22]: s Out[22]: 0 1 1 2 2 <NA> dtype: Int64 In [23]: s[2] Out[23]: <NA> In [24]: s[2] is pd.NA Out[24]: True 目前,pandas 尚未使用NA默认使用 aDataFrame或 的这些数据类型Series,因此您需要显式指定 dtype。转换部分解释了转换为这些数据类型的简单方法 。 算术和比较运算中的传播# 一般来说,缺失值会在涉及 的操作中传播NA。当其中一个操作数未知时,运算的结果也是未知的。 例如,NA在算术运算中传播,类似于 np.nan: In [25]: pd.NA + 1 Out[25]: <NA> In [26]: "a" * pd.NA Out[26]: <NA> 在一些特殊情况下,结果是已知的,即使操作数之一是NA。 In [27]: pd.NA ** 0 Out[27]: 1 In [28]: 1 ** pd.NA Out[28]: 1 在相等和比较运算中,NA也会传播。这偏离了np.nan, 与 的比较np.nan总是返回的行为False。 In [29]: pd.NA == 1 Out[29]: <NA> In [30]: pd.NA == pd.NA Out[30]: <NA> In [31]: pd.NA < 2.5 Out[31]: <NA> 要检查值是否等于NA,请使用isna() In [32]: pd.isna(pd.NA) Out[32]: True 笔记 此基本传播规则的一个例外是缩减(例如平均值或最小值),其中 pandas 默认跳过缺失值。更多信息请参见 计算部分。 逻辑运算# 对于逻辑运算,遵循三值逻辑(或 Kleene 逻辑,类似于 R、SQL 和 Julia)NA的规则 。此逻辑意味着仅在逻辑需要时才传播缺失值。 例如,对于逻辑“或”运算 ( |),如果其中一个操作数是True,我们已经知道结果将为True,而不管其他值如何(因此无论缺失值都是True或False)。在这种情况下,NA不会传播: In [33]: True | False Out[33]: True In [34]: True | pd.NA Out[34]: True In [35]: pd.NA | True Out[35]: True 另一方面,如果其中一个操作数是False,则结果取决于另一个操作数的值。因此,在这种情况下NA 传播: In [36]: False | True Out[36]: True In [37]: False | False Out[37]: False In [38]: False | pd.NA Out[38]: <NA> 逻辑“与”运算 ( ) 的行为&可以使用类似的逻辑导出(如果操作数之一已经是 ,则 nowNA不会传播False): In [39]: False & True Out[39]: False In [40]: False & False Out[40]: False In [41]: False & pd.NA Out[41]: False In [42]: True & True Out[42]: True In [43]: True & False Out[43]: False In [44]: True & pd.NA Out[44]: <NA> NA在布尔上下文中# 由于 NA 的实际值未知,因此将 NA 转换为布尔值是不明确的。 In [45]: bool(pd.NA) --------------------------------------------------------------------------- TypeError Traceback (most recent call last) Cell In[45], line 1 ----> 1 bool(pd.NA) File missing.pyx:392, in pandas._libs.missing.NAType.__bool__() TypeError: boolean value of NA is ambiguous 这也意味着NA不能在计算为布尔值的上下文中使用,例如where can might be 。在这种情况下,可用于检查或避免,例如通过预先填充缺失值。if condition: ...conditionNAisna()NAconditionNA 在语句中使用SeriesorDataFrame对象时会出现类似的情况,请参阅在 pandas 中使用 if/truth 语句。if NumPy ufunc # pandas.NA实现 NumPy 的__array_ufunc__协议。大多数 ufunc 与 一起工作NA,并且通常返回NA: In [46]: np.log(pd.NA) Out[46]: <NA> In [47]: np.add(pd.NA, 1) Out[47]: <NA> 警告 目前,ufuncs 涉及 ndarray 并将NA返回一个填充 NA 值的对象数据类型。 In [48]: a = np.array([1, 2, 3]) In [49]: np.greater(a, pd.NA) Out[49]: array([<NA>, <NA>, <NA>], dtype=object) 这里的返回类型将来可能会更改以返回不同的数组类型。 有关 ufunc 的更多信息,请参阅DataFrame 与 NumPy 函数的互操作性。 转换# 如果您有DataFrameor Seriesusing np.nan, Series.convert_dtypes()并且DataFrame.convert_dtypes() 可以将数据转换为使用使用or 等DataFrame数据类型。在从推断数据类型的 IO 方法读取数据集后,这尤其有用。NAInt64DtypeArrowDtype 在此示例中,虽然所有列的数据类型均已更改,但我们显示前 10 列的结果。 In [50]: import io In [51]: data = io.StringIO("a,b\n,True\n2,") In [52]: df = pd.read_csv(data) In [53]: df.dtypes Out[53]: a float64 b object dtype: object In [54]: df_conv = df.convert_dtypes() In [55]: df_conv Out[55]: a b 0 <NA> True 1 2 <NA> In [56]: df_conv.dtypes Out[56]: a Int64 b boolean dtype: object 插入缺失数据# 您可以通过简单地分配给 aSeries或来插入缺失值DataFrame。将根据数据类型选择使用的缺失值哨兵。 In [57]: ser = pd.Series([1., 2., 3.]) In [58]: ser.loc[0] = None In [59]: ser Out[59]: 0 NaN 1 2.0 2 3.0 dtype: float64 In [60]: ser = pd.Series([pd.Timestamp("2021"), pd.Timestamp("2021")]) In [61]: ser.iloc[0] = np.nan In [62]: ser Out[62]: 0 NaT 1 2021-01-01 dtype: datetime64[ns] In [63]: ser = pd.Series([True, False], dtype="boolean[pyarrow]") In [64]: ser.iloc[0] = None In [65]: ser Out[65]: 0 <NA> 1 False dtype: bool[pyarrow] 对于object类型,pandas 将使用给定的值: In [66]: s = pd.Series(["a", "b", "c"], dtype=object) In [67]: s.loc[0] = None In [68]: s.loc[1] = np.nan In [69]: s Out[69]: 0 None 1 NaN 2 c dtype: object 缺失数据的计算# 缺失值通过 pandas 对象之间的算术运算传播。 In [70]: ser1 = pd.Series([np.nan, np.nan, 2, 3]) In [71]: ser2 = pd.Series([np.nan, 1, np.nan, 4]) In [72]: ser1 Out[72]: 0 NaN 1 NaN 2 2.0 3 3.0 dtype: float64 In [73]: ser2 Out[73]: 0 NaN 1 1.0 2 NaN 3 4.0 dtype: float64 In [74]: ser1 + ser2 Out[74]: 0 NaN 1 NaN 2 NaN 3 7.0 dtype: float64 数据结构概述中讨论的描述性统计和计算方法 (并在此处和此处列出)都是针对缺失数据的说明。 对数据求和时,NA 值或空数据将被视为零。 In [75]: pd.Series([np.nan]).sum() Out[75]: 0.0 In [76]: pd.Series([], dtype="float64").sum() Out[76]: 0.0 取乘积时,NA值或空数据将被视为1。 In [77]: pd.Series([np.nan]).prod() Out[77]: 1.0 In [78]: pd.Series([], dtype="float64").prod() Out[78]: 1.0 默认情况下,累积方法(如cumsum()和cumprod() 忽略 NA 值)将它们保留在结果中。可以通过以下方式更改此行为skipna 默认情况下,累积方法cumsum()会cumprod()忽略 NA 值,但会将它们保留在结果数组中。要覆盖此行为并包含 NA 值,请使用skipna=False。 In [79]: ser = pd.Series([1, np.nan, 3, np.nan]) In [80]: ser Out[80]: 0 1.0 1 NaN 2 3.0 3 NaN dtype: float64 In [81]: ser.cumsum() Out[81]: 0 1.0 1 NaN 2 4.0 3 NaN dtype: float64 In [82]: ser.cumsum(skipna=False) Out[82]: 0 1.0 1 NaN 2 NaN 3 NaN dtype: float64 删除丢失的数据# dropna()dropa 缺少数据的行或列。 In [83]: df = pd.DataFrame([[np.nan, 1, 2], [1, 2, np.nan], [1, 2, 3]]) In [84]: df Out[84]: 0 1 2 0 NaN 1 2.0 1 1.0 2 NaN 2 1.0 2 3.0 In [85]: df.dropna() Out[85]: 0 1 2 2 1.0 2 3.0 In [86]: df.dropna(axis=1) Out[86]: 1 0 1 1 2 2 2 In [87]: ser = pd.Series([1, pd.NA], dtype="int64[pyarrow]") In [88]: ser.dropna() Out[88]: 0 1 dtype: int64[pyarrow] 填充缺失数据# 按值填充# fillna()用非 NA 数据替换 NA 值。 将 NA 替换为标量值 In [89]: data = {"np": [1.0, np.nan, np.nan, 2], "arrow": pd.array([1.0, pd.NA, pd.NA, 2], dtype="float64[pyarrow]")} In [90]: df = pd.DataFrame(data) In [91]: df Out[91]: np arrow 0 1.0 1.0 1 NaN <NA> 2 NaN <NA> 3 2.0 2.0 In [92]: df.fillna(0) Out[92]: np arrow 0 1.0 1.0 1 0.0 0.0 2 0.0 0.0 3 2.0 2.0 向前或向后填补空白 In [93]: df.ffill() Out[93]: np arrow 0 1.0 1.0 1 1.0 1.0 2 1.0 1.0 3 2.0 2.0 In [94]: df.bfill() Out[94]: np arrow 0 1.0 1.0 1 2.0 2.0 2 2.0 2.0 3 2.0 2.0 限制填充的 NA 值的数量 In [95]: df.ffill(limit=1) Out[95]: np arrow 0 1.0 1.0 1 1.0 1.0 2 NaN <NA> 3 2.0 2.0 NA 值可以替换为来自 或 的相应值,Series其中DataFrame 索引和列在原始对象和填充对象之间对齐。 In [96]: dff = pd.DataFrame(np.arange(30, dtype=np.float64).reshape(10, 3), columns=list("ABC")) In [97]: dff.iloc[3:5, 0] = np.nan In [98]: dff.iloc[4:6, 1] = np.nan In [99]: dff.iloc[5:8, 2] = np.nan In [100]: dff Out[100]: A B C 0 0.0 1.0 2.0 1 3.0 4.0 5.0 2 6.0 7.0 8.0 3 NaN 10.0 11.0 4 NaN NaN 14.0 5 15.0 NaN NaN 6 18.0 19.0 NaN 7 21.0 22.0 NaN 8 24.0 25.0 26.0 9 27.0 28.0 29.0 In [101]: dff.fillna(dff.mean()) Out[101]: A B C 0 0.00 1.0 2.000000 1 3.00 4.0 5.000000 2 6.00 7.0 8.000000 3 14.25 10.0 11.000000 4 14.25 14.5 14.000000 5 15.00 14.5 13.571429 6 18.00 19.0 13.571429 7 21.00 22.0 13.571429 8 24.00 25.0 26.000000 9 27.00 28.0 29.000000 笔记 DataFrame.where()也可以用来填充NA值。结果与上面相同。 In [102]: dff.where(pd.notna(dff), dff.mean(), axis="columns") Out[102]: A B C 0 0.00 1.0 2.000000 1 3.00 4.0 5.000000 2 6.00 7.0 8.000000 3 14.25 10.0 11.000000 4 14.25 14.5 14.000000 5 15.00 14.5 13.571429 6 18.00 19.0 13.571429 7 21.00 22.0 13.571429 8 24.00 25.0 26.000000 9 27.00 28.0 29.000000 插值# DataFrame.interpolate()并Series.interpolate()使用各种插值方法填充 NA 值。 In [103]: df = pd.DataFrame( .....: { .....: "A": [1, 2.1, np.nan, 4.7, 5.6, 6.8], .....: "B": [0.25, np.nan, np.nan, 4, 12.2, 14.4], .....: } .....: ) .....: In [104]: df Out[104]: 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.40 In [105]: df.interpolate() Out[105]: 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 In [106]: idx = pd.date_range("2020-01-01", periods=10, freq="D") In [107]: data = np.random.default_rng(2).integers(0, 10, 10).astype(np.float64) In [108]: ts = pd.Series(data, index=idx) In [109]: ts.iloc[[1, 2, 5, 6, 9]] = np.nan In [110]: ts Out[110]: 2020-01-01 8.0 2020-01-02 NaN 2020-01-03 NaN 2020-01-04 2.0 2020-01-05 4.0 2020-01-06 NaN 2020-01-07 NaN 2020-01-08 0.0 2020-01-09 3.0 2020-01-10 NaN Freq: D, dtype: float64 In [111]: ts.plot() Out[111]: <Axes: > In [112]: ts.interpolate() Out[112]: 2020-01-01 8.000000 2020-01-02 6.000000 2020-01-03 4.000000 2020-01-04 2.000000 2020-01-05 4.000000 2020-01-06 2.666667 2020-01-07 1.333333 2020-01-08 0.000000 2020-01-09 3.000000 2020-01-10 3.000000 Freq: D, dtype: float64 In [113]: ts.interpolate().plot() Out[113]: <Axes: > Timestamp通过设置DatetimeIndex 可以相对于 a 进行插值method="time" In [114]: ts2 = ts.iloc[[0, 1, 3, 7, 9]] In [115]: ts2 Out[115]: 2020-01-01 8.0 2020-01-02 NaN 2020-01-04 2.0 2020-01-08 0.0 2020-01-10 NaN dtype: float64 In [116]: ts2.interpolate() Out[116]: 2020-01-01 8.0 2020-01-02 5.0 2020-01-04 2.0 2020-01-08 0.0 2020-01-10 0.0 dtype: float64 In [117]: ts2.interpolate(method="time") Out[117]: 2020-01-01 8.0 2020-01-02 6.0 2020-01-04 2.0 2020-01-08 0.0 2020-01-10 0.0 dtype: float64 对于浮点索引,请使用method='values': In [118]: idx = [0.0, 1.0, 10.0] In [119]: ser = pd.Series([0.0, np.nan, 10.0], idx) In [120]: ser Out[120]: 0.0 0.0 1.0 NaN 10.0 10.0 dtype: float64 In [121]: ser.interpolate() Out[121]: 0.0 0.0 1.0 5.0 10.0 10.0 dtype: float64 In [122]: ser.interpolate(method="values") Out[122]: 0.0 0.0 1.0 1.0 10.0 10.0 dtype: float64 如果您安装了scipy,则可以将一维插值例程的名称传递给method.如 scipy 插值文档和参考指南中所指定。适当的插值方法取决于数据类型。 提示 如果您正在处理以不断增加的速度增长的时间序列,请使用method='barycentric'。 如果您的值接近累积分布函数,请使用method='pchip'。 为了平滑绘图使用的目标来填充缺失值method='akima'。 In [123]: df = pd.DataFrame( .....: { .....: "A": [1, 2.1, np.nan, 4.7, 5.6, 6.8], .....: "B": [0.25, np.nan, np.nan, 4, 12.2, 14.4], .....: } .....: ) .....: In [124]: df Out[124]: 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.40 In [125]: df.interpolate(method="barycentric") Out[125]: 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.400 In [126]: df.interpolate(method="pchip") Out[126]: 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.400000 In [127]: df.interpolate(method="akima") Out[127]: 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 [128]: df.interpolate(method="spline", order=2) Out[128]: 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.400000 In [129]: df.interpolate(method="polynomial", order=2) Out[129]: 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 [130]: np.random.seed(2) In [131]: ser = pd.Series(np.arange(1, 10.1, 0.25) ** 2 + np.random.randn(37)) In [132]: missing = np.array([4, 13, 14, 15, 16, 17, 18, 20, 29]) In [133]: ser.iloc[missing] = np.nan In [134]: methods = ["linear", "quadratic", "cubic"] In [135]: df = pd.DataFrame({m: ser.interpolate(method=m) for m in methods}) In [136]: df.plot() Out[136]: <Axes: > 从扩展数据中插入新的观察结果Series.reindex()。 In [137]: ser = pd.Series(np.sort(np.random.uniform(size=100))) # interpolate at new_index In [138]: new_index = ser.index.union(pd.Index([49.25, 49.5, 49.75, 50.25, 50.5, 50.75])) In [139]: interp_s = ser.reindex(new_index).interpolate(method="pchip") In [140]: interp_s.loc[49:51] Out[140]: 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 插值限制# interpolate()接受关键字参数来限制自上次有效观察以来填充的limit连续值的数量NaN In [141]: ser = pd.Series([np.nan, np.nan, 5, np.nan, np.nan, np.nan, 13, np.nan, np.nan]) In [142]: ser Out[142]: 0 NaN 1 NaN 2 5.0 3 NaN 4 NaN 5 NaN 6 13.0 7 NaN 8 NaN dtype: float64 In [143]: ser.interpolate() Out[143]: 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 In [144]: ser.interpolate(limit=1) Out[144]: 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方向。 In [145]: ser.interpolate(limit=1, limit_direction="backward") Out[145]: 0 NaN 1 5.0 2 5.0 3 NaN 4 NaN 5 11.0 6 13.0 7 NaN 8 NaN dtype: float64 In [146]: ser.interpolate(limit=1, limit_direction="both") Out[146]: 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 In [147]: ser.interpolate(limit_direction="both") Out[147]: 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无论值是被现有有效值包围还是在现有有效值之外,都会填充值。该limit_area 参数限制填充为内部或外部值。 # fill one consecutive inside value in both directions In [148]: ser.interpolate(limit_direction="both", limit_area="inside", limit=1) Out[148]: 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 [149]: ser.interpolate(limit_direction="backward", limit_area="outside") Out[149]: 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 [150]: ser.interpolate(limit_direction="both", limit_area="outside") Out[150]: 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 替换值# Series.replace()andDataFrame.replace()可以类似于 Series.fillna()andDataFrame.fillna()用来替换或插入缺失值。 In [151]: df = pd.DataFrame(np.eye(3)) In [152]: df Out[152]: 0 1 2 0 1.0 0.0 0.0 1 0.0 1.0 0.0 2 0.0 0.0 1.0 In [153]: df_missing = df.replace(0, np.nan) In [154]: df_missing Out[154]: 0 1 2 0 1.0 NaN NaN 1 NaN 1.0 NaN 2 NaN NaN 1.0 In [155]: df_filled = df_missing.replace(np.nan, 2) In [156]: df_filled Out[156]: 0 1 2 0 1.0 2.0 2.0 1 2.0 1.0 2.0 2 2.0 2.0 1.0 通过传递一个列表可以替换多个值。 In [157]: df_filled.replace([1, 44], [2, 28]) Out[157]: 0 1 2 0 2.0 2.0 2.0 1 2.0 2.0 2.0 2 2.0 2.0 2.0 使用映射字典替换。 In [158]: df_filled.replace({1: 44, 2: 28}) Out[158]: 0 1 2 0 44.0 28.0 28.0 1 28.0 44.0 28.0 2 28.0 28.0 44.0 正则表达式替换# 笔记 r以字符为前缀的 Python 字符串 是“原始”字符串。它们对于反斜杠的语义与没有此前缀的字符串不同。原始字符串中的反斜杠将被解释为转义的反斜杠,例如。r'hello world'r'\' == '\\' 更换 '。'和NaN In [159]: d = {"a": list(range(4)), "b": list("ab.."), "c": ["a", "b", np.nan, "d"]} In [160]: df = pd.DataFrame(d) In [161]: df.replace(".", np.nan) Out[161]: a b c 0 0 a a 1 1 b b 2 2 NaN NaN 3 3 NaN d 更换 '。' with NaNwith 正则表达式删除周围的空格 In [162]: df.replace(r"\s*\.\s*", np.nan, regex=True) Out[162]: a b c 0 0 a a 1 1 b b 2 2 NaN NaN 3 3 NaN d 替换为正则表达式列表。 In [163]: df.replace([r"\.", r"(a)"], ["dot", r"\1stuff"], regex=True) Out[163]: a b c 0 0 astuff astuff 1 1 b b 2 2 dot NaN 3 3 dot d 替换为映射字典中的正则表达式。 In [164]: df.replace({"b": r"\s*\.\s*"}, {"b": np.nan}, regex=True) Out[164]: a b c 0 0 a a 1 1 b b 2 2 NaN NaN 3 3 NaN d 传递使用regex关键字的正则表达式的嵌套字典。 In [165]: df.replace({"b": {"b": r""}}, regex=True) Out[165]: a b c 0 0 a a 1 1 b 2 2 . NaN 3 3 . d In [166]: df.replace(regex={"b": {r"\s*\.\s*": np.nan}}) Out[166]: a b c 0 0 a a 1 1 b b 2 2 NaN NaN 3 3 NaN d In [167]: df.replace({"b": r"\s*(\.)\s*"}, {"b": r"\1ty"}, regex=True) Out[167]: a b c 0 0 a a 1 1 b b 2 2 .ty NaN 3 3 .ty d 传递将用标量替换匹配项的正则表达式列表。 In [168]: df.replace([r"\s*\.\s*", r"a|b"], "placeholder", regex=True) Out[168]: a b c 0 0 placeholder placeholder 1 1 placeholder placeholder 2 2 placeholder NaN 3 3 placeholder d 所有正则表达式示例也可以将 to_replace参数作为regex参数进行传递。在这种情况下,value 参数必须按名称显式传递,或者regex必须是嵌套字典。 In [169]: df.replace(regex=[r"\s*\.\s*", r"a|b"], value="placeholder") Out[169]: a b c 0 0 placeholder placeholder 1 1 placeholder placeholder 2 2 placeholder NaN 3 3 placeholder d 笔记 from 的正则表达式对象re.compile也是有效的输入。