【问题标题】:Reshift Nan values column dataframe if match with list如果与列表匹配,则重新移动 Nan 值列数据框
【发布时间】:2021-02-22 00:15:33
【问题描述】:

我想重新排列包含 Nan 的列名值。

我想要的条件是,如果列表中的字符串与列 [1] 匹配,它只会重新移动包含匹配字符串下的行的列值,因此它是我移动前的数据框。

[in] : df
[Out]:

   column1     column2    column3 
0  aba abab    800.0      900.0
1  aaa acc     900.0      60.0 
2  bba jka     809.0      400.0
3  fff yy      521.0      490.0  
4  hkm asa j   290.0      321.0    
5  daa rr oo   88.0       Nan
6  jtuy ww ddw Nan        600.0
8  bkam ftf    Nan        Nan   
9  fgqefc      Nan        Nan
10 daas we fg  Nan        Nan   
11 judv mm mk  Nan        Nan   
12 hus gg hhh  Nan        Nan 

这里是我的清单

my_list= ['bba jka', 'hkm asa j']

这是我想要的数据框,名称为 df1

column1     column2    column3 
0  aba abab    800.0      900.0
1  aaa acc     900.0      60.0 
2  bba jka     Nan        Nan
3  fff yy      809.0      400.0  
4  hkm asa j   Nan        Nan    
5  daa rr oo   521.0      490.0
6  jtuy ww ddw 290.0      321.0
8  bkam ftf    88.0       Nan   
9  fgqefc      Nan        600.0
10 daas we fg  Nan        Nan   
11 judv mm mk  Nan        Nan   
12 hus gg hhh  Nan        Nan 

我不明白怎么用shift和match实现df1,谁能解决?

【问题讨论】:

    标签: python pandas list dataframe shift


    【解决方案1】:

    这里有一个建议,可能不是最佳的:

    第一步apply的准备工作:

    match = df['column1'].str.fullmatch('|'.join(entry for entry in my_list))
    df['shift'] = match.cumsum()
    df['index'] = df.index
    df.set_index('column1', drop=True, inplace=True)
    

    结果 (df) 看起来像:

                column2 column3  shift  index
    column1                                  
    aba abab      800.0   900.0      0      0
    aaa acc       900.0    60.0      0      1
    bba jka       809.0   400.0      1      2
    fff yy        521.0   490.0      1      3
    hkm asa j     290.0   321.0      2      4
    daa rr oo      88.0     NaN      2      5
    ...
    

    第 2 步:通过 applyNaN 通过掩码 match 进行“转移”:

    df = df.apply(lambda row: df.shift(int(row.at['shift'])).iloc[int(row.at['index'])],
                  axis='columns')
    df[list(match)] = np.nan
    

    第 3 步:清理:

    df.drop(['shift', 'index'], axis='columns', inplace=True)
    df.reset_index(inplace=True)
    

    希望结果符合预期:

            column1 column2 column3
    0      aba abab   800.0   900.0
    1       aaa acc   900.0    60.0
    2       bba jka     NaN     NaN
    3        fff yy   809.0   400.0
    4     hkm asa j     NaN     NaN
    5     daa rr oo   521.0   490.0
    6   jtuy ww ddw   290.0   321.0
    7      bkam ftf    88.0     NaN
    8        fgqefc     NaN   600.0
    9    daas we fg     NaN     NaN
    10   judv mm mk     NaN     NaN
    11   hus gg hhh     NaN     NaN
    

    但我不喜欢在apply 中使用df.shift。问题是如果没有shift第一行中可能的匹配会导致错误结果。这是避免此问题的版本,并且在apply 中更直接:

    # Preparation
    df = pd.concat(
            [pd.DataFrame({col: ['NOT IN LIST' if i == 0 else np.nan]
                           for i, col in enumerate(df.columns)}), df],
            axis='index', 
            ignore_index=True
        )
    match = df['column1'].str.fullmatch('|'.join(entry for entry in my_list))
    df['shift'] = df.index - match.cumsum()
    df.set_index('column1', drop=True, inplace=True)
    
    # Shifting etc.
    df = df.apply(lambda row: df.iloc[int(row.at['shift'])], axis='columns')
    df[list(match)] = np.nan
    
    # Clean up
    df.drop('NOT IN LIST', axis='index', inplace=True)
    df.drop('shift', axis='columns', inplace=True)
    df.reset_index(inplace=True)
    

    (这里假设字符串'NOT IN LIST'不在my_list中。空字符串''很可能也是一个不错的选择。)

    【讨论】:

    • 感谢您的cmets,对我很有帮助。但是,在您的第一个代码中,我无法操作它,它显示“new_values [tuple(axis_indexer)] = fill_value”。当我在 google collab 上启动它时出现问题,它说“切片索引必须是整数或无或具有 index 方法”。
    • 但是,这个链接和这个问题之间的区别是我已经完成了将列字符串值实现为完美句子,而不是正则表达式。所以我认为这就足够了。
    • 有关我的表格的更多详细信息,您能否查看我想要使用您的代码执行的真实数据框以及究竟发生了什么问题,您可以查看我的链接stackoverflow.com/questions/64785356/…
    • @MRifkyFerdiand 我已经调整了两个版本的代码,它现在应该可以工作了。我现在很清楚错误的原因。请参阅我对您的question 的回复。
    • 天哪.. 感谢您花这么多时间来创建和评估我的代码。它适用于流程,我已经接受了你的代码兄弟..
    猜你喜欢
    • 2021-02-23
    • 1970-01-01
    • 1970-01-01
    • 2022-07-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多