将条件函数应用于数十亿个数据点

时间:2017-09-09 20:44:07

标签: python pandas numpy

我有一个如下所示的数据框:

UIModalPresentationStyle GetAdaptivePresentationStyle

我想申请:

public class PopoverDelegate : UIPopoverPresentationControllerDelegate
{
    public delegate void DatePicked(NSDate date);
    UIDatePicker datePicker;
    DatePicked datePicked;

    public PopoverDelegate(UIDatePicker datePicker, DatePicked datePicked)
    {
        this.datePicked = datePicked;
        this.datePicker = datePicker;
    }

    public override UIModalPresentationStyle GetAdaptivePresentationStyle(UIPresentationController forPresentationController)
    {
        return UIModalPresentationStyle.None;
    }

    public override void DidDismissPopover(UIPopoverPresentationController popoverPresentationController)
    {
        datePicked(datePicker.Date);
    }
}

我独立尝试的内容:

<!DOCTYPE html> <html> <head> <title>Portfolio V1</title> <link rel="stylesheet" type="text/css" href="main.css"/> <script type="text/javascript"></script> </head> <body> <img src="images/test1.png" onmouseover="this.src=images/test2.png" onmouseout="this.src='test1.png'" > </body> </html>

idx a b c d e f g h i j 1 0 17 17 83 17 0 21 16 21 4 2 -9 31 31 74 40 0 39 39 39 9 3 -27 0 -27 92 27 -37 3 -37 40 16 4 -4 0 -4 81 4 -1 5 5 6 9

哪种方式似乎有效..按顺序运行这两个操作将无法工作,因为数据帧在第一个操作后从int转换为float,并使原始值与日志值无法区分,例如。它是0还是log(1)= 0?

我也担心这些错误:

除以零

where x>0: functionA(x)

where x<0: functionB(x)

无效值

df[df>0] = np.log(df)

这不应该发生,因为没有df[df<0] = -np.log(-df)值,我明确选择非零值。

usr/local/anaconda3/envs/ds/lib/python3.6/site-packages/ipykernel_launcher.py:1: RuntimeWarning: divide by zero encountered in log
  """Entry point for launching an IPython kernel.```

最后一个问题是如何有效地完成这项工作,因为我正在使用数十亿行。

3 个答案:

答案 0 :(得分:1)

您可以使用numpy.piecewise功能:https://docs.scipy.org/doc/numpy-1.13.0/reference/generated/numpy.piecewise.html

import numpy as np
positive = df.values > 0
negative = df.values < 0
df[:] = np.piecewise(df.values, (positive, negative), (np.log, lambda x: -np.log(-x)))

答案 1 :(得分:0)

这可能是一种更好的方式,但就目前而言,我的所作所为:

将我的专栏分为三类:

  1. ( - INF,0)
  2. (0,inf)
  3. ( - inf,inf)
  4. 前两个是直截了当的[1]:

    for i in [a, ...]:
        s = df[i]
        df[i] = np.where(s<0, -np.log(-s), s).astype('float32')
    

    类似于2的代码。

    类型3更棘手,更慢:

    def apply_log(x):
        if x>0:
            return np.log(x)
        elif x<0:
            return -np.log(-x)
        elif x == 0:
            return 0.0
        else:
            assert False
    

    然后将其矢量化[2]

    veclog = np.vectorize(apply_log)

    然后运行它: df['c'] = veclog(s.astype('float32')).astype('float32')

    〜50M子集上的运行时: 57.7 s ± 142 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

    从[3]到np.where,fn在条件之前应用,因此除以零错误。类型1和2抛出除以零警告/错误,类型3没有错误。

    来源:

    [1] Python: numpy/pandas change values on condition

    [2] Function application over numpy's matrix row/column

    [3] RuntimeWarning: divide by zero encountered in log

答案 2 :(得分:0)

之前有人添加了这个答案,然后删除了它:

df = np.log(df.where(df>0)).fillna(-1*np.log(-1*df.where(df<0))).fillna(0)

其中使用了大块内存但似乎有效。 我怀疑它已被删除,因为它按顺序运行ops并可能破坏某些值。

更新:这似乎与.0005中其他解决方案的答案相符。如果原始海报会重新发布他们的答案,那就好了!