如果系列是全 nan,或者剩余的非 nan 条目为零,如何有效地填充 na(0)?
How to efficiently fillna(0) if series is all-nan, or else remaining non-nan entries are zero?
鉴于我有一个 pandas 系列,如果 all 值为 NaN 或者 all,我想用零填充 NaN 值为零或 NaN。
例如,我想用零填充以下系列中的 NaN。
0 0
1 0
2 NaN
3 NaN
4 NaN
5 NaN
6 NaN
7 NaN
8 NaN
但是,我不想填充na(0)以下系列:
0 0
1 0
2 2
3 0
4 NaN
5 NaN
6 NaN
7 NaN
8 NaN
我正在查看文档,似乎我可以使用 pandas.Series.value_counts 来确保值仅为 0 和 NaN,然后只需调用 fillna(0)。换句话说,我希望检查是否 set(s.unique().astype(str)).issubset(['0.0','nan']), THEN fillna(0), 否则不要.
考虑到 pandas 的强大功能,似乎有更好的方法可以做到这一点。有没有人有任何建议来干净高效地执行此操作?
感谢 cᴏʟᴅsᴘᴇᴇᴅ
的潜在解决方案
if s.dropna().eq(0).all():
s = s.fillna(0)
你可以用0
和isna
比较,如果只有NaN
s和0
然后fillna
:
if ((s == 0) | (s.isna())).all():
s = pd.Series(0, index=s.index)
或比较唯一值:
if pd.Series(s.unique()).fillna(0).eq(0).all():
s = pd.Series(0, index=s.index)
@cᴏʟᴅsᴘᴇᴇᴅ解决方案,谢谢 - 比较没有 NaN
s 和 dropna
的系列:
if s.dropna().eq(0).all():
s = pd.Series(0, index=s.index)
问题的解决方案 - 需要转换为 string
s,因为 :
if set(s.unique().astype(str)).issubset(['0.0','nan']):
s = pd.Series(0, index=s.index)
时间:
s = pd.Series(np.random.choice([0,np.nan], size=10000))
In [68]: %timeit ((s == 0) | (s.isna())).all()
The slowest run took 4.85 times longer than the fastest. This could mean that an intermediate result is being cached.
1000 loops, best of 3: 574 µs per loop
In [69]: %timeit pd.Series(s.unique()).fillna(0).eq(0).all()
1000 loops, best of 3: 587 µs per loop
In [70]: %timeit s.dropna().eq(0).all()
The slowest run took 4.65 times longer than the fastest. This could mean that an intermediate result is being cached.
1000 loops, best of 3: 774 µs per loop
In [71]: %timeit set(s.unique().astype(str)).issubset(['0.0','nan'])
The slowest run took 5.78 times longer than the fastest. This could mean that an intermediate result is being cached.
10000 loops, best of 3: 157 µs per loop
为空值创建一个掩码。检查掩码的长度是否等于序列的长度(在这种情况下,序列要么全为空值要么为空),或者非空值是否全部等于零。如果是这样,请使用该系列中的原始索引创建一个新的零值系列。
nulls = s.isnull()
if len(nulls) == len(s) or s[~nulls].eq(0).all():
s = pd.Series(0, index=s.index)
计时
%%timeit s_ = pd.concat([s] * 100000)
nulls = s_.isnull()
if len(nulls) == len(s_) or s_[~nulls].eq(0).all():
s_ = pd.Series(0, index=s_.index)
# 100 loops, best of 3: 2.33 ms per loop
# OP's solution:
%%timeit s_ = pd.concat([s] * 100000)
if s_.dropna().eq(0).all():
s_ = s_.fillna(0)
# 10 loops, best of 3: 19.7 ms per loop
# @Jezrael's fastest solution:
%%timeit s_ = pd.concat([s] * 100000)
if set(s_.unique().astype(str)).issubset(['0.0','nan']):
s_ = pd.Series(0, index=s_.index)
# 1000 loops, best of 3: 4.58 ms per loop
鉴于我有一个 pandas 系列,如果 all 值为 NaN 或者 all,我想用零填充 NaN 值为零或 NaN。
例如,我想用零填充以下系列中的 NaN。
0 0
1 0
2 NaN
3 NaN
4 NaN
5 NaN
6 NaN
7 NaN
8 NaN
但是,我不想填充na(0)以下系列:
0 0
1 0
2 2
3 0
4 NaN
5 NaN
6 NaN
7 NaN
8 NaN
我正在查看文档,似乎我可以使用 pandas.Series.value_counts 来确保值仅为 0 和 NaN,然后只需调用 fillna(0)。换句话说,我希望检查是否 set(s.unique().astype(str)).issubset(['0.0','nan']), THEN fillna(0), 否则不要.
考虑到 pandas 的强大功能,似乎有更好的方法可以做到这一点。有没有人有任何建议来干净高效地执行此操作?
感谢 cᴏʟᴅsᴘᴇᴇᴅ
的潜在解决方案if s.dropna().eq(0).all():
s = s.fillna(0)
你可以用0
和isna
比较,如果只有NaN
s和0
然后fillna
:
if ((s == 0) | (s.isna())).all():
s = pd.Series(0, index=s.index)
或比较唯一值:
if pd.Series(s.unique()).fillna(0).eq(0).all():
s = pd.Series(0, index=s.index)
@cᴏʟᴅsᴘᴇᴇᴅ解决方案,谢谢 - 比较没有 NaN
s 和 dropna
的系列:
if s.dropna().eq(0).all():
s = pd.Series(0, index=s.index)
问题的解决方案 - 需要转换为 string
s,因为
if set(s.unique().astype(str)).issubset(['0.0','nan']):
s = pd.Series(0, index=s.index)
时间:
s = pd.Series(np.random.choice([0,np.nan], size=10000))
In [68]: %timeit ((s == 0) | (s.isna())).all()
The slowest run took 4.85 times longer than the fastest. This could mean that an intermediate result is being cached.
1000 loops, best of 3: 574 µs per loop
In [69]: %timeit pd.Series(s.unique()).fillna(0).eq(0).all()
1000 loops, best of 3: 587 µs per loop
In [70]: %timeit s.dropna().eq(0).all()
The slowest run took 4.65 times longer than the fastest. This could mean that an intermediate result is being cached.
1000 loops, best of 3: 774 µs per loop
In [71]: %timeit set(s.unique().astype(str)).issubset(['0.0','nan'])
The slowest run took 5.78 times longer than the fastest. This could mean that an intermediate result is being cached.
10000 loops, best of 3: 157 µs per loop
为空值创建一个掩码。检查掩码的长度是否等于序列的长度(在这种情况下,序列要么全为空值要么为空),或者非空值是否全部等于零。如果是这样,请使用该系列中的原始索引创建一个新的零值系列。
nulls = s.isnull()
if len(nulls) == len(s) or s[~nulls].eq(0).all():
s = pd.Series(0, index=s.index)
计时
%%timeit s_ = pd.concat([s] * 100000)
nulls = s_.isnull()
if len(nulls) == len(s_) or s_[~nulls].eq(0).all():
s_ = pd.Series(0, index=s_.index)
# 100 loops, best of 3: 2.33 ms per loop
# OP's solution:
%%timeit s_ = pd.concat([s] * 100000)
if s_.dropna().eq(0).all():
s_ = s_.fillna(0)
# 10 loops, best of 3: 19.7 ms per loop
# @Jezrael's fastest solution:
%%timeit s_ = pd.concat([s] * 100000)
if set(s_.unique().astype(str)).issubset(['0.0','nan']):
s_ = pd.Series(0, index=s_.index)
# 1000 loops, best of 3: 4.58 ms per loop