【问题标题】:Pandas/xarray - Shift horizontally values dynamically based on another dataframePandas/xarray - 基于另一个数据帧动态水平移动值
【发布时间】:2021-10-13 23:47:34
【问题描述】:

我想在另一个数据帧df_x 的相应行中的值之后水平移动我的数据帧test_1 的每一行。 df_x 每行中的值应该定义向左移动的步数。

test_1 = pd.DataFrame([[1,2,3,4], [10,12,13,14], [20, 22, 23,24]])

df_x = pd.DataFrame([[1],[3],[2]])

我的预期输出是:

Out[157]: 
    0   1   2   3
0   2   3   4  NA
1  14  NA  NA  NA
2  23  24  NA  NA

我尝试从一个类似问题 (how to shift columns in pandas DataFrame dynamically and independently?) 的答案中进行调整,并使用了这个: test_1.apply(lambda x: x.shift(periods = -df_x.loc[x,:]), axis = 1).

但是,我不断收到以下错误:

KeyError: "Passing list-likes to .loc or [] with any missing labels is no longer supported. The following labels were missing: Int64Index([3, 4], dtype='int64'). See https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#deprecate-loc-reindex-listlike"

PS:如果有人也知道如何在不从 Xarray 转换为 Pandas 的情况下做到这一点,那就更好了。

【问题讨论】:

    标签: python pandas dataframe python-xarray


    【解决方案1】:

    我看到@tlentali 回答了你的问题作为替代答案,你也可以使用这个:

    df_x_seq = np.squeeze((df_x.values))
    Lens=np.squeeze((test_1.shape[1]-df_x).values)
        Id=-1
    def shift(row):
        global Id
        Id+=1
        array=np.empty((row.shape[0]))
        array[:]=np.nan
        if Lens[Id]!=row.shape[0]:
            array[:Lens[Id]]=row.values[df_x_seq[Id]:]
            return  array 
        else:
            return row
     
    

    【讨论】:

    • 感谢您的回复。答案似乎有效,但是当我更改df_x = pd.DataFrame([[2],[2],[3]]) 时,出现错误:ValueError: could not broadcast input array from shape (3,) into shape (1,)
    • 谢谢!实际上,我遇到了 df_x_seq 未定义的问题。
    • 哦,它只是 df_x 的压缩版本。
    • 是的,它运行良好。我接受了另一个答案,因为它排在第一位,但这个答案也很完美。感谢您的宝贵时间!
    【解决方案2】:

    来自您的DataFrame

    >>> test_1 = pd.DataFrame([[1,2,3,4], [10,12,13,14], [20, 22, 23,24]])
    >>> test_1
        0   1   2   3
    0   1   2   3   4
    1   10  12  13  14
    2   20  22  23  24
    

    我们可以像这样转置DataFrame 开始:

    >>> test_1 = test_1.T
    >>> test_1
        0   1   2
    0   1   10  20
    1   2   12  22
    2   3   13  23
    3   4   14  24
    

    然后,使用df_x,我们可以使用for 循环选择正确的列到shift 并再次重新转置test_1 以获得预期的结果:

    >>> df_x = pd.DataFrame([[0],[1],[2]])
    >>> line=0
    >>> for val in list(df_x.values.flatten()): 
    ...     test_1[line] = test_1[line].shift(periods=-val)
    ...     line+=1
    >>> test_1 = test_1.T
        0       1       2       3
    0   1.0     2.0     3.0     4.0
    1   12.0    13.0    14.0    NaN
    2   23.0    24.0    NaN     NaN
    

    对于df_x = pd.DataFrame([[0],[2],[2]])

    >>> test_1 = pd.DataFrame([[1,2,3,4], [10,12,13,14], [20, 22, 23,24]]) 
    >>> test_1 = test_1.T 
    >>> df_x = pd.DataFrame([[0],[2],[2]]) 
    
    >>> line=0
    >>> for val in list(df_x.values.flatten()): 
    ...     test_1[line] = test_1[line].shift(periods=-val)
    ...     line+=1  
    >>> test_1 = test_1.T         
    >>> test_1
        0       1       2   3
    0   1.0     2.0     3.0 4.0
    1   13.0    14.0    NaN NaN
    2   23.0    24.0    NaN NaN
    

    对于df_x = pd.DataFrame([[2],[2],[0]])

    >>> test_1 = pd.DataFrame([[1,2,3,4], [10,12,13,14], [20, 22, 23,24]]) 
    >>> test_1 = test_1.T 
    >>> df_x = pd.DataFrame([[2],[2],[0]]) 
    
    >>> line=0
    >>> for val in list(df_x.values.flatten()): 
    ...     test_1[line] = test_1[line].shift(periods=-val)
    ...     line+=1  
    >>> test_1 = test_1.T         
    >>> test_1
        0       1       2       3
    0   3.0     4.0     NaN     NaN
    1   13.0    14.0    NaN     NaN
    2   20.0    22.0    23.0    24.0
    

    对于df_x = pd.DataFrame([[1],[3],[2]])

    >>> test_1 = pd.DataFrame([[1,2,3,4], [10,12,13,14], [20, 22, 23,24]]) 
    >>> test_1 = test_1.T 
    >>> df_x = pd.DataFrame([[1],[3],[2]]) 
    
    >>> line=0
    >>> for val in list(df_x.values.flatten()): 
    ...     test_1[line] = test_1[line].shift(periods=-val)
    ...     line+=1  
    >>> test_1 = test_1.T         
    >>> test_1
        0       1       2     3
    0   2.0     3.0     4.0   NaN
    1   14.0    NaN     NaN   NaN
    2   23.0    24.0    NaN   NaN
    

    【讨论】:

    • 非常感谢您的回答。它运行良好,但如果我将我的 df_x[0],[1],[2] 更改为 [0],[2],[2],结果将停止工作:test_1 = pd.DataFrame([[1,2,3,4], [10,12,13, 14], [20, 22, 23,24]]) test_1 = test_1.T df_x = pd.DataFrame([[0],[2],[2]]) for val in df_x.values: test_1[val[ 0]] = test_1[val[0]].shift(periods=-val[0]) test_1 = test_1.T test_1 Out[285]: 0 1 2 3 0 1.0 2.0 3.0 4.0 1 10.0 12.0 13.0 14.0 2 NaN NaN NaN NaN
    • 我更新了答案以涵盖您的第二个示例。它解决了你的问题吗?
    • 当您在问题中添加了一个新示例时,我更新了我的答案。
    【解决方案3】:

    还有第三个回答也很好,但不知为何被删了。

    解决方案:

    test_2=(df_x.rename(columns={0:'s'})
                .join(test_1)
                .apply(lambda x:x.shift(-(x['s'])),axis=1)
                .drop(columns=['s']))
    

    【讨论】:

      猜你喜欢
      • 2021-05-27
      • 1970-01-01
      • 1970-01-01
      • 2019-05-25
      • 2018-02-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-06-25
      相关资源
      最近更新 更多