pythonpandas

"Cannot set a DataFrame with multiple columns to the single column ..."


I have the following dataframe:

Price                       Adj Close       Close        High         Low        Open    Volume      ema_10      ema_20      ema_40      ema_50       sma_5      sma_10      n_high       n_low
Ticker                           AAPL        AAPL        AAPL        AAPL        AAPL      AAPL
Date
2023-11-13 00:00:00+00:00  183.899063  184.800003  186.029999  184.210007  185.820007  43627500  184.800003  184.800003  184.800003  184.800003         NaN         NaN         NaN         NaN
2023-11-14 00:00:00+00:00  186.526199  187.440002  188.110001  186.300003  187.699997  60108400  185.280003  185.051432  184.928784  184.903532         NaN         NaN         NaN         NaN
2023-11-15 00:00:00+00:00  187.093430  188.009995  189.500000  187.779999  187.850006  53790500  185.776365  185.333199  185.079086  185.025354         NaN         NaN         NaN         NaN
2023-11-16 00:00:00+00:00  188.785126  189.710007  190.960007  188.649994  189.570007  54412900  186.491573  185.750038  185.304985  185.209066         NaN         NaN         NaN         NaN
2023-11-17 00:00:00+00:00  188.765244  189.690002  190.380005  188.570007  190.250000  50922700  187.073105  186.125273  185.518888  185.384789  187.930002         NaN         NaN         NaN
...                               ...         ...         ...         ...         ...       ...         ...         ...         ...         ...         ...         ...         ...         ...
2024-11-04 00:00:00+00:00  221.766006  222.009995  222.789993  219.710007  220.990005  44944500  228.087639  228.953961  227.718509  226.698000  226.920001  229.660001  236.850006  219.710007
2024-11-05 00:00:00+00:00  223.204422  223.449997  223.949997  221.139999  221.800003  28111300  227.244431  228.429774  227.510289  226.570628  224.876001  228.419000  236.850006  219.710007
2024-11-06 00:00:00+00:00  222.475235  222.720001  226.070007  221.190002  222.610001  54561100  226.421808  227.885986  227.276616  226.419623  223.400000  227.615001  236.850006  219.710007
2024-11-06 00:00:00+00:00  222.475235  222.720001  226.070007  221.190002  222.610001  54561100  226.421808  227.885986  227.276616  226.419623  223.400000  227.615001  236.850006  219.710007
2024-11-06 00:00:00+00:00  222.475235  222.720001  226.070007  221.190002  222.610001  54561100  226.421808  227.885986  227.276616  226.419623  223.400000  227.615001  236.850006  219.710007
2024-11-06 00:00:00+00:00  222.475235  222.720001  226.070007  221.190002  222.610001  54561100  226.421808  227.885986  227.276616  226.419623  223.400000  227.615001  236.850006  219.710007
2024-11-07 00:00:00+00:00  227.229996  227.479996  227.880005  224.570007  224.630005  42137700  226.614206  227.847321  227.286537  226.461206  223.713998  227.306000  236.850006  219.710007

And I'm trying to create a new column using the following statement:

dfDaily['%K'] = (dfDaily['Close'] - dfDaily['n_low']) * 100 / (dfDaily['n_high'] - dfDaily['n_low'])

But I get the following error message:

Traceback (most recent call last):
  File "C:\DEV\Fiverr2024\ORDER\VanaromHuot\stockMA6.py", line 107, in <module>
    dfDaily['%K'] = (dfDaily['Close'] - dfDaily['n_low']) * 100 / (dfDaily['n_high'] - dfDaily['n_low'])
    ~~~~~~~^^^^^^
  File "C:\DEV\.venv\yfinance\Lib\site-packages\pandas\core\frame.py", line 4301, in __setitem__
    self._set_item_frame_value(key, value)
  File "C:\DEV\.venv\yfinance\Lib\site-packages\pandas\core\frame.py", line 4459, in _set_item_frame_value
    raise ValueError(
ValueError: Cannot set a DataFrame with multiple columns to the single column %K

Solution

  • If there is only one ticker, here AAPL:

    Because MultiIndex in columns, it is possible to remove the second level of MultiIndex (Ticker level) by DataFrame.droplevel:

    dfDaily = dfDaily.droplevel(axis=1, level=1)
    dfDaily['%K'] = ((dfDaily['Close'] - dfDaily['n_low']) * 100 / 
                     (dfDaily['n_high'] - dfDaily['n_low']))
    

    If output is one column DataFrame, it is possible to select it:

    dfDaily['%K'] = ((dfDaily['Close'] - dfDaily['n_low']) * 100 / 
                     (dfDaily['n_high'] - dfDaily['n_low'])['AAPL'])
    

    If there are multiple tickers:

    df = ((dfDaily['Close'] - dfDaily['n_low']) * 100 / 
          (dfDaily['n_high'] - dfDaily['n_low']).add_prefix('%K_'))
    
    out = pd.concat([dfDaily, df], axis=1)