计算组内的差异

时间:2016-03-18 06:42:34

标签: python python-3.x pandas

我有一个.state('sign-in', { parent: 'unlogged', url: '^/sign-in', ... }) .state('sign-up', { parent: 'unlogged', url: '^/sign-up', ... }); ,其行一次提供一个功能的值。时间由时间列标识(大约有1000000个不同的时间)。功能由功能列标识(有几十个功能)。对于功能和时间的任何组合,最多只有一行。每次只有部分功能可用;唯一的例外是功能0,它始终可用。我想在DataFrame添加一列,显示当时功能0的值。有没有一种合理的快速方法呢?

例如,假设我有

DataFrame

我想添加一个包含[2,2,3,3,3,7,7]。

的列

我尝试使用df = pd.DataFrame({ 'time': [1,1,2,2,2,3,3], 'feature': [1,0,0,2,4,3,0], 'value':[1,2,3,4,5,6,7], }) 和布尔索引,但没有运气。

3 个答案:

答案 0 :(得分:3)

  

我想在该DataFrame中添加一列,显示当时功能0的值。有没有一种合理的快速方法呢?

我认为groupby(这是一项相当昂贵的操作)对此来说太过分了。尝试merge只使用0功能的值:

>>> pd.merge(
        df,
        df[df.feature == 0].drop('feature', axis=1).rename(columns={'value': 'value_0'}))
    feature     time    value   value_0
0   1   1   1   2
1   0   1   2   2
2   0   2   3   3
3   2   2   4   3
4   4   2   5   3
5   3   3   6   7
6   0   3   7   7

修改

Per @ jezrael的要求,这是一个时间测试:

 import pandas as pd

 m = 10000

 df = pd.DataFrame({
   'time': range(m / 2) + range(m / 2),
   'feature': range(m / 2) + [0] * (m / 2),
   'value': range(m),
 })

在这个输入上,@ jezrael的解决方案需要396毫秒,而我的需要4.03毫秒。

答案 1 :(得分:0)

如果您要删除零行并将其添加为单独的列(与原始请求略有不同),则可以执行以下操作:

# Create initial dataframe.
df = pd.DataFrame({
  'time': [1,1,2,2,2,3,3],
  'feature': [1,0,0,2,4,3,0],
  'value':[1,2,3,4,5,6,7],
})

# Set the index to 'time'
df = df.set_index('time')

# Join the zero feature value to the non-zero feature rows.
>>> df.loc[df.feature > 0, :].join(df.loc[df.feature == 0, 'value'], rsuffix='_feature_0')
      feature  value  value_feature_0
time                                 
1           1      1                2
2           2      4                3
2           4      5                3
3           3      6                7

答案 2 :(得分:0)

您可以valueset_indexgroupby transform idxmin

如果0列中的值featuremin,则此解决方案有效。

df = df.set_index('value')

df['diff'] = df.groupby('time')['feature'].transform('idxmin')
print df.reset_index()
   value  feature  time  diff
0      1        1     1     2
1      2        0     1     2
2      3        0     2     3
3      4        2     2     3
4      5        4     2     3
5      6        3     3     7
6      7        0     3     7