pandas版本的numpy的ones_like

时间:2016-11-16 17:15:16

标签: python pandas numpy

考虑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

什么是更好的方式?

3 个答案:

答案 0 :(得分:2)

一种方式(不确定它是否是最佳方式)是使用逐元素划分和fillna方法。即使原始0中有np.nanSeries,也应该有效。 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。在这种情况下,我将简单介绍。