考虑pd.Series
s
s = pd.Series([.4, .5, .6], list('abc'))
s
a 0.4
b 0.5
c 0.6
dtype: float64
我之前已经完成了这个以获得一系列
pd.Series(np.ones_like(s.values), s.index, name=s.name)
a 1.0
b 1.0
c 1.0
dtype: float64
什么是更好的方式?
答案 0 :(得分:2)
一种方式(不确定它是否是最佳方式)是使用逐元素划分和fillna
方法。即使原始0
中有np.nan
和Series
,也应该有效。 E.g。
>>> a = pandas.Series(np.array([0,np.nan,2,3,4]), list('abcde'))
>>> a
a 0.0
b NaN
c 2.0
d 3.0
e 4.0
dtype: float64
>>> (a/a).fillna(1)
a 1.0
b 1.0
c 1.0
d 1.0
e 1.0
dtype: float64
答案 1 :(得分:2)
您可以使用Series.copy
并禁用它的deep
参数来加速整个过程。稍后,使用ndarray.fill
以1填充系列中的所有值。
让我们用DF
来说明其值是Nan
的一半:
np.random.seed(42)
df = pd.DataFrame(np.random.randn(10**6,), columns=['A'])
# Populate values with Nans
df.loc[df.sample(frac=0.5).index] = np.NaN
df.shape
# (1000000, 1)
def fill_ones_with_modify():
ser = df['A'].copy(deep=False) # use copy() → without modifying the original DF
ser.values.fill(1)
return ser
%timeit fill_ones_with_modify()
1000 loops, best of 3: 837 µs per loop
注意: 这会在系列中运行inplace
,因此DF
的结果系列也会被更改(填充1' S)
另一种方法是将系列作为DF
的单个列访问,并在复制后将其展平以返回系列对象。然而,当复制基础数据和索引时,这需要更多时间。 Upside - 不修改引用的系列对象。
def fill_ones_without_modify():
ser = df[['A']].copy(deep=False).squeeze()
ser.values.fill(1)
return ser
%timeit fill_ones_without_modify()
100 loops, best of 3: 6.4 ms per loop
答案 2 :(得分:0)
这个问题是在我提出问题之后的2019年2月21日〜2.5年才提出的。我意识到我永远不会真正使用我提出的内容,而只是去做
processed_already
在这种情况下,Pandas将为我们在整个索引中广播pd.Series(1, s.index, name=s.name)
。我喜欢它,因为它很简单。但是,这并不快
假设我有
1
然后是时间
s = pd.Series(5, range(int(1e6)))
我对那个级别的微优化不感兴趣。 IMO 413已经足够接近369。在这种情况下,我将简单介绍。