【问题标题】:How to for loop list all values into a dataframe? Python如何for循环将所有值列出到数据框中? Python
【发布时间】:2017-03-28 00:47:42
【问题描述】:

我有一个要修改的数据框。
我还有三个列表可以引用数据框的每个部分以执行计算。

signal
['signal0', 'signal1']
df_list
['A', 'B']
df_ma2_list
['A_MA', 'B_MA']

到目前为止,我的数据框还不错:

        A_MA    B_MA    A   B   signal0 signal1
      0 NaN      NaN    50  55     0      0
      1 NaN      NaN    55  67     0      0
      2 65.00   70.33   90  89     0      0
      3 54.67   63.33   19  34     0      0
      4 64.00   68.33   83  82     0      0
      5 64.33   70.33   91  95     0      0
      6 81.33   91.33   70  97     0      0
      7 86.33   95.00   98  93     0      0
      8 83.33   98.33   82  105    0      0
      9 86.67   102.67  80  110    0      0

我可以对 A 列和 A_MA 列和 B 列和 B_MA 进行手动计算,以便生成 1 或 -1 的信号,如下所示:

 df2.loc[df2.A > df2.A_MA, "signal0"] = -1
 df2.loc[df2.A < df2.A_MA, "signal0"] = 1

 df2.loc[df2.B > df2.B_MA, "signal1"] = -1
 df2.loc[df2.B < df2.B_MA, "signal1"] = 1
 round(df2,1)     

我得到了正确的输出,其中 signal0 和 signal1 分别适用于带有 A_MA 的 A 和带有 B_MA 的 B。 因此,例如,在第 7 行中,B = 105 且 B_MA =98,因此 signal1 = -1。 同样在第 7 行,A= 82 和 A_MA = 83,所以 signal0 = 1。

            A_MA    B_MA    A   B   signal0 signal1
          0 NaN      NaN    50  55    -1    -1
          1 NaN      NaN    55  67    -1    -1
          2 65.0     70.3   90  89     1     1
          3 54.7     63.3   19  34    -1    -1
          4 64.0     68.3   83  82     1     1
          5 64.3     70.3   91  95     1     1
          6 81.3     91.3   70  97    -1     1
          7 86.3     95.0   98  93     1    -1
          8 83.3    98.3    82  105   -1     1
          9 86.7    102.7   80  110   -1     1

上述方法对于更大的数据帧来说太长了。 所以我想使用三个列表的 for 循环,无论有多少列,我都必须自动计算数据框。因此,如果我有 A 到 Z 列、A_MA - Z_MA 和 signal0 到 signal26 列。它将仅根据 df_list、df_ma2_list 和 signal 三个股票代码列表计算所有信号。 我使用了这个等式,但它只在信号 0 和信号 1 列中为 B 和 B_MB 提供了相同的信号。

   for i in signal:
      for x in df_list:
            for f in df_ma2_list:

                df2.loc[df2["{}".format(x)] > df2["{}".format(f)],  "{}".format(i)] = -1                   
                df2.loc[df2["{}".format(x)] < df2["{}".format(f)], "{}".format(i)] = 1

            A_MA    B_MA    A   B   signal0 signal1
          0 NaN      NaN    50  55     0      0
          1 NaN      NaN    55  67     0      0
          2 65.00   70.33   90  89    -1     -1
          3 54.67   63.33   19  34     1      1
          4 64.00   68.33   83  82    -1     -1
          5 64.33   70.33   91  95    -1     -1
          6 81.33   91.33   70  97    -1     -1
          7 86.33   95.00   98  93     1      1
          8 83.33   98.33   82  105   -1     -1
          9 86.67   102.67  80  110   -1     -1

此外,不幸的是,使用 np.where 会产生相同的数据帧问题,两个信号列具有相同的值。

 import numpy as np

 for f in signal:
     for i in df_list:
        for x in df_ma_list:

             df3["{}".format(f)] = np.where((df3["{}".format(i)] > df3["{}".format(x)]), 1, -1)   
             df3["{}".format(f)] = np.where((df3["{}".format(i)] > df3["{}".format(x)]), 1, -1)   

df3

我需要使用上面的代码和三个列表的 for 循环来为两列获取正确的信号。如果有更好的方法,请告诉我。对不起,很长的问题!非常感谢。

【问题讨论】:

  • 也许看看numpy.where
  • 您好,感谢您的建议。不幸的是,我已经尝试过 np.where 并且它给了我同样的问题。
  • 您得到的 B 和 B_MB 信号相同,因为您没有将 A 与 A_MA 联系起来,将 B 与 B_MA 联系起来。更深入地看看你的 for 循环;您正在将 A 与 B 进行比较...
  • 哇,谢谢!快没希望了。我看到您对所有列表只使用了一个 for 循环; ts、ma 和信号。那讲得通。大约 2-3 个月前,我才开始使用 Python 来完成我的金融数学论文。大解脱。再次感谢 not_a_robot!
  • 不客气。如果您满意,请点击投票旁边的复选标记接受答案:)

标签: python list for-loop dataframe format


【解决方案1】:
>>> import pandas as pd
>>> import numpy as np
>>> import string

让我们创建一些数据:

>>> data = {letter: np.random.randn(100000) for letter in string.ascii_uppercase}
>>> data.update({letter + '_MA': np.random.randn(100000) for letter in string.ascii_uppercase})
>>> df = pd.DataFrame(data)
>>> df.head()
          A      A_MA         B      B_MA         C      C_MA         D  \
0  0.194264  1.026269 -0.754151 -0.156895  1.583709 -0.018520  0.895973   
1 -0.105569 -0.380830 -1.464730 -2.057322 -0.448863 -0.270909 -1.011525   
2  1.306095  0.003583 -0.714843  0.132892 -0.162723  0.494365 -0.702625   
3  0.194403 -0.828941  0.472967  1.218849 -0.092833  1.639822 -1.953157   
4 -0.680198  0.078923  0.939365 -0.267072  0.275587  2.262286 -0.196426   

       D_MA         E      E_MA    ...            V      V_MA         W  \
0 -0.185024  0.803631 -0.415856    ...    -0.042800  0.439730 -0.197314   
1 -0.784399 -0.758771  0.531884    ...    -0.560350  0.588178  0.527035   
2  0.476952 -0.160694  1.397329    ...    -0.889000  0.667174  0.578487   
3  1.755312 -0.191594 -0.701020    ...     1.092291  0.711403  0.726068   
4  0.195957  1.222551  1.071865    ...    -0.869672 -0.315218 -1.400713   

       W_MA         X      X_MA         Y      Y_MA         Z      Z_MA  
0 -0.942320 -1.918997  1.792692 -1.656744  0.739270 -2.486536 -0.289948  
1  2.065264 -1.257320 -1.636223  0.910484 -0.771143  2.084536  0.413396  
2 -1.049890  1.888866 -1.658292 -0.494236  0.980870  1.139787  1.085633  
3 -1.144944  0.314362 -0.183625  0.148545 -0.214450 -0.992381  1.300748  
4 -1.220797  1.049443  1.171045 -0.403457  0.868933  1.985064 -0.842899  

[5 rows x 52 columns]

接下来,我们将每个字母与其相应的移动平均线 (MA) 和信号列配对:

>>> columns = [(letter, letter + '_MA', 'signal' + str(ord(letter)-65)) for letter in string.ascii_uppercase]
>>> columns
[('A', 'A_MA', 'signal0'), ('B', 'B_MA', 'signal1'), ('C', 'C_MA', 'signal2'), ('D', 'D_MA', 'signal3'), ('E', 'E_MA', 'signal4'), ('F', 'F_MA', 'signal5'), ('G', 'G_MA', 'signal6'), ('H', 'H_MA', 'signal7'), ('I', 'I_MA', 'signal8'), ('J', 'J_MA', 'signal9'), ('K', 'K_MA', 'signal10'), ('L', 'L_MA', 'signal11'), ('M', 'M_MA', 'signal12'), ('N', 'N_MA', 'signal13'), ('O', 'O_MA', 'signal14'), ('P', 'P_MA', 'signal15'), ('Q', 'Q_MA', 'signal16'), ('R', 'R_MA', 'signal17'), ('S', 'S_MA', 'signal18'), ('T', 'T_MA', 'signal19'), ('U', 'U_MA', 'signal20'), ('V', 'V_MA', 'signal21'), ('W', 'W_MA', 'signal22'), ('X', 'X_MA', 'signal23'), ('Y', 'Y_MA', 'signal24'), ('Z', 'Z_MA', 'signal25')]

对于每个常规时间序列,其移动平均值,以及对应的signal 列,如果常规时间序列大于移动平均值,则分配 -1,否则分配 1。

>>> for ts, ma, signal in columns:
...     df[signal] = np.where(df[ts] > df[ma], -1, 1)
... 
>>> df.head()
          A      A_MA         B      B_MA         C      C_MA         D  \
0  0.194264  1.026269 -0.754151 -0.156895  1.583709 -0.018520  0.895973   
1 -0.105569 -0.380830 -1.464730 -2.057322 -0.448863 -0.270909 -1.011525   
2  1.306095  0.003583 -0.714843  0.132892 -0.162723  0.494365 -0.702625   
3  0.194403 -0.828941  0.472967  1.218849 -0.092833  1.639822 -1.953157   
4 -0.680198  0.078923  0.939365 -0.267072  0.275587  2.262286 -0.196426   

       D_MA         E      E_MA    ...     signal16  signal17  signal18  \
0 -0.185024  0.803631 -0.415856    ...           -1         1        -1   
1 -0.784399 -0.758771  0.531884    ...            1         1        -1   
2  0.476952 -0.160694  1.397329    ...           -1         1        -1   
3  1.755312 -0.191594 -0.701020    ...            1         1        -1   
4  0.195957  1.222551  1.071865    ...            1        -1         1   

   signal19  signal20  signal21  signal22  signal23  signal24  signal25  
0        -1        -1         1        -1         1         1         1  
1         1         1         1         1        -1        -1        -1  
2        -1        -1         1        -1        -1         1        -1  
3        -1        -1        -1        -1        -1        -1         1  
4         1        -1         1         1         1         1        -1  

[5 rows x 78 columns]

下面是仔细看看:

>>> df[list(columns[0]) + list(columns[1])].head()
          A      A_MA  signal0         B      B_MA  signal1
0  0.194264  1.026269        1 -0.754151 -0.156895        1
1 -0.105569 -0.380830       -1 -1.464730 -2.057322       -1
2  1.306095  0.003583       -1 -0.714843  0.132892        1
3  0.194403 -0.828941       -1  0.472967  1.218849        1
4 -0.680198  0.078923        1  0.939365 -0.267072       -1

您必须准确决定在这种情况下要做什么,例如,A 等于 A_MA 对于给定的行(在您的方法中,只需使用 &gt;&lt;没有 &lt;=&gt;= 会排除潜在的相等行。

【讨论】:

    【解决方案2】:

    对于列表,请使用 zip,如下所示:

       zip_list = list(zip(df_list, df_ma2_list, signal))
    

    这给出了以下内容:

       zip_list
    
       [('A', 'A_MA', 'signal0'), ('B', 'B_MA', 'signal1'), ('C', 'C_MA', 'signal2')]
    

    然后 zip_list 可用于单个 for 循环,如下所示:

            for df_list, df_ma2_list, signal in zip_list:
                  df[signal] = np.where(df[df_list] > df[df_ma2_list], -1, 1)
    

    ​ 希望对可能有点困惑的人有所帮助。再次感谢 not_a_robot :)

    【讨论】:

      猜你喜欢
      • 2021-03-08
      • 1970-01-01
      • 1970-01-01
      • 2011-10-02
      • 2020-09-11
      • 2021-03-15
      • 1970-01-01
      • 2020-07-17
      • 1970-01-01
      相关资源
      最近更新 更多