Pandas:在多列上逐行进行操作

3

我有两个标量变量 A 和 B,还有一个 DataFrame df1,其中有 1000 列和 86400 行。为了简单起见,下表只展示了 10 列:

        0            1         2            3            4          5            6           7          8            9         f  
0   4.000000    23.000000   6.000000    36.000000   37.000000   33.000000   22.000000   28.000000   8.000000    14.000000   50.135
1   4.002361    23.002361   6.002361    36.002361   37.002361   33.002361   22.002361   28.002361   8.002361    14.002361   50.130
2   4.004722    23.004722   6.004722    36.004722   37.004722   33.004722   22.004722   28.004722   8.004722    14.004722   50.120
3   4.007083    23.007083   6.007083    36.007083   37.007083   33.007083   22.007083   28.007083   8.007083    14.007083   50.112
4   4.009444    23.009444   6.009444    36.009444   37.009444   33.009444   22.009444   28.009444   8.009444    14.009444   50.102
5   4.011806    23.011806   6.011806    36.011806   37.011806   33.011806   22.011806   28.011806   8.011806    14.011806   50.097
    ...     ...     ...     ...     ...     ...     ...     ...     ...     ...     ...     ...
86387   207.969306  226.969306  209.969306  239.969306  240.969306  236.969306  225.969306  231.969306  211.969306  217.969306  49.920
86388   207.971667  226.971667  209.971667  239.971667  240.971667  236.971667  225.971667  231.971667  211.971667  217.971667  49.920
86389   207.974028  226.974028  209.974028  239.974028  240.974028  236.974028  225.974028  231.974028  211.974028  217.974028  49.920
86390   207.976389  226.976389  209.976389  239.976389  240.976389  236.976389  225.976389  231.976389  211.976389  217.976389  49.920
86391   207.978750  226.978750  209.978750  239.978750  240.978750  236.978750  225.978750  231.978750  211.978750  217.978750  49.917
86392   207.981111  226.981111  209.981111  239.981111  240.981111  236.981111  225.981111  231.981111  211.981111  217.981111  49.917
86393   207.983472  226.983472  209.983472  239.983472  240.983472  236.983472  225.983472  231.983472  211.983472  217.983472  49.915
86394   207.985833  226.985833  209.985833  239.985833  240.985833  236.985833  225.985833  231.985833  211.985833  217.985833  49.915
86395   207.988194  226.988194  209.988194  239.988194  240.988194  236.988194  225.988194  231.988194  211.988194  217.988194  49.915
86396   207.990556  226.990556  209.990556  239.990556  240.990556  236.990556  225.990556  231.990556  211.990556  217.990556  49.912
86397   207.992917  226.992917  209.992917  239.992917  240.992917  236.992917  225.992917  231.992917  211.992917  217.992917  49.915
86398   207.995278  226.995278  209.995278  239.995278  240.995278  236.995278  225.995278  231.995278  211.995278  217.995278  49.917
86399   207.997639  226.997639  209.997639  239.997639  240.997639  236.997639  225.997639  231.997639  211.997639  217.997639  49.917

我希望执行逐行操作:

当f>50时:将C=A/B/3600添加到1-999列中的值。

当f<50时:从1-999列中的值中减去C=A/B/3600。

cols = df1.columns[df1.columns.isin(range(0, 999))]
df1[cols] = np.where(df1[cols] > 50, 
             df1[cols].values - np.arange(len(df1))[:, None] * C, 
             df1[cols].values + np.arange(len(df1))[:, None] * C)

可以看到,即使f<50,值仍然在不断增加。

有什么建议吗? 提前感谢您的回复。

1个回答

1
使用 numpy.where,并根据条件添加 numpy.arange,如果性能很重要:
cols = df.columns[df.columns.isin(range(1, 1000))]
df[cols] = np.where(df[cols] > 50, 
                    df[cols].values - np.arange(len(df))[:, None], 
                    df[cols].values + np.arange(len(df))[:, None])

print (df)
        0   1   2   3   4   5   6   7   8   9  991  992  993  994  995  996  \
0      18   8   9   5  38  11  26  25   2  30   23   18   34    1   29   34   
1      18   9  10   6  39  12  27  26   3  31   24   19   35    2   30   35   
2      18  10  11   7  40  13  28  27   4  32   25   20   36    3   31   36   
3      18  11  12   8  41  14  29  28   5  33   26   21   37    4   32   37   
4      18  12  13   9  42  15  30  29   6  34   27   22   38    5   33   38   
5      18  13  14  10  43  16  31  30   7  35   28   23   39    6   34   39   
6      18  14  15  11  44  17  32  31   8  36   29   24   40    7   35   40   
86393  18  15  16  12  45  18  33  32   9  37   30   25   41    8   36   41   
86394  18  16  17  13  46  19  34  33  10  38   31   26   42    9   37   42   
86395  18  17  18  14  47  20  35  34  11  39   32   27   43   10   38   43   
86396  18  18  19  15  48  21  36  35  12  40   33   28   44   11   39   44   
86397  18  19  20  16  49  22  37  36  13  41   34   29   45   12   40   45   
86398  18  20  21  17  50  23  38  37  14  42   35   30   46   13   41   46   
86399  18  21  22  18  51  24  39  38  15  43   36   31   47   14   42   47   
86400  18  22  23  19  52  25  40  39  16  44   37   32   48   15   43   48   

       997  998  999       f  
0       25   15    2  50.135  
1       26   16    3  50.130  
2       27   17    4  50.120  
3       28   18    5  50.112  
4       29   19    6  50.102  
5       30   20    7  50.097  
6       31   21    8  50.095  
86393   32   22    9  49.915  
86394   33   23   10  49.915  
86395   34   24   11  49.915  
86396   35   25   12  49.912  
86397   36   26   13  49.915  
86398   37   27   14  49.917  
86399   38   28   15  49.917  
86400   39   29   16  49.915  

编辑:
A = 360000
B = 5
C = A/B/3600

cols = df.columns[df.columns.isin(range(1, 1000))]
mask = df[cols] > 50

df[cols] = np.where(mask, 
                    df[cols].values - mask.cumsum().sub(1) * C, 
                    df[cols].values + (~mask).cumsum().sub(1) * C)

print (df)
                0           1           2           3           4           5  \
0        4.000000   23.000000    6.000000   36.000000   37.000000   33.000000   
1        4.002361   43.002361   26.002361   56.002361   57.002361   53.002361   
2        4.004722   63.004722   46.004722   76.004722   77.004722   73.004722   
3        4.007083   83.007083   66.007083   96.007083   97.007083   93.007083   
4        4.009444  103.009444   86.009444  116.009444  117.009444  113.009444   
5        4.011806  123.011806  106.011806  136.011806  137.011806  133.011806   
86387  207.969306  226.969306  209.969306  239.969306  240.969306  236.969306   
86388  207.971667  206.971667  189.971667  219.971667  220.971667  216.971667   
86389  207.974028  186.974028  169.974028  199.974028  200.974028  196.974028   
86390  207.976389  166.976389  149.976389  179.976389  180.976389  176.976389   
86391  207.978750  146.978750  129.978750  159.978750  160.978750  156.978750   
86392  207.981111  126.981111  109.981111  139.981111  140.981111  136.981111   
86393  207.983472  106.983472   89.983472  119.983472  120.983472  116.983472   
86394  207.985833   86.985833   69.985833   99.985833  100.985833   96.985833   
86395  207.988194   66.988194   49.988194   79.988194   80.988194   76.988194   
86396  207.990556   46.990556   29.990556   59.990556   60.990556   56.990556   
86397  207.992917   26.992917    9.992917   39.992917   40.992917   36.992917   
86398  207.995278    6.995278  -10.004722   19.995278   20.995278   16.995278   
86399  207.997639  -13.002361  -30.002361   -0.002361    0.997639   -3.002361   

                6           7           8           9       f  
0       22.000000   28.000000    8.000000   14.000000  50.135  
1       42.002361   48.002361   28.002361   34.002361  50.130  
2       62.004722   68.004722   48.004722   54.004722  50.120  
3       82.007083   88.007083   68.007083   74.007083  50.112  
4      102.009444  108.009444   88.009444   94.009444  50.102  
5      122.011806  128.011806  108.011806  114.011806  50.097  
86387  225.969306  231.969306  211.969306  217.969306  49.920  
86388  205.971667  211.971667  191.971667  197.971667  49.920  
86389  185.974028  191.974028  171.974028  177.974028  49.920  
86390  165.976389  171.976389  151.976389  157.976389  49.920  
86391  145.978750  151.978750  131.978750  137.978750  49.917  
86392  125.981111  131.981111  111.981111  117.981111  49.917  
86393  105.983472  111.983472   91.983472   97.983472  49.915  
86394   85.985833   91.985833   71.985833   77.985833  49.915  
86395   65.988194   71.988194   51.988194   57.988194  49.915  
86396   45.990556   51.990556   31.990556   37.990556  49.912  
86397   25.992917   31.992917   11.992917   17.992917  49.915  
86398    5.995278   11.995278   -8.004722   -2.004722  49.917  
86399  -14.002361   -8.002361  -28.002361  -22.002361  49.917  

谢谢,看起来更好了,但是如果f<50,它仍然会添加(而不是减去)C。 - Luca91
f>50的部分是完美的,它按照预期增加。只有f>50的部分在不断增加,而不是减少。 - Luca91
@Luca91 - 已将您的新数据添加到答案输出中。 - jezrael
@Luca91 - 我觉得我找到了问题,给我一些时间。 - jezrael
@Luca91 - 请现在检查。 - jezrael
显示剩余12条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接