【问题标题】:Python - Shift Data to a different ROWPython - 将数据转移到不同的行
【发布时间】:2020-08-19 15:46:43
【问题描述】:

如果IDCODE 匹配,我对数据框有点陌生,并且一直在尝试找到将特定列中的数据转移到另一行的解决方案。

    df = pd.DataFrame({'ID': ['123', '123', '123', '154', '167', '167'], 
                   'NAME': ['Adam', 'Adam', 'Adam', 'Bob', 'Charlie', 'Charlie'],
                   'CODE': ['1001', '1001', '1011', '1002', 'A0101', 'A0101'],
                   'TAG1': ['A123', 'B123', 'K123', 'D123', 'E123', 'G123'],
                   'TAG2': [ np.NaN, 'C123', 'L123', np.NaN, 'F123', 'H123'],
                   'TAG3': [ np.NaN, 'M123', np.NaN, np.NaN, np.NaN, np.NaN]})
    ID    NAME      CODE    TAG1    TAG2    TAG3
0   123   Adam      1001    A123    NaN     NaN
1   123   Adam      1001    B123    C123    M123
2   123   Adam      1011    K123    L123    NaN
3   154   Bob       1002    D123    NaN     NaN
4   167   Charlie   A0101   E123    F123    NaN
5   167   Charlie   A0101   G123    H123    NaN

所以上面我添加了描述初始数据帧的代码,现在我们可以看到ID='123' 有两行代码相同,'TAG' 列中的值不同,我想移动 @987654330 @第二行的数据到'TAG1'之后的第一行或'TAG1'中的数据,如果为空,则完全删除第二行。 ID='167' 应该是一样的。

下面是另一个代码,其中包含我手动添加的示例数据框,它描述了最终结果,任何建议都会很棒。我尝试了一件事,它完全没有按照我想要的方式工作。

    df_result = pd.DataFrame({'ID': ['123', '123', '154', '167'], 
                   'NAME': ['Adam', 'Adam', 'Bob', 'Charlie',],
                   'CODE': ['1001', '1011', '1002', 'A0101'],
                   'TAG1': ['A123', 'K123', 'D123', 'E123'],
                   'TAG2': ['B123', 'L123', np.NaN, 'F123'],
                   'TAG3': ['C123', np.NaN, np.NaN, 'G123'],
                   'TAG4': ['M123', np.NaN, np.NaN, 'H123']})
     ID     NAME    CODE    TAG1    TAG2    TAG3    TAG4
0    123    Adam    1001    A123    B123    C123    M123
1    123    Adam    1011    K123    L123    NaN     NaN
2    154    Bob     1002    D123    NaN     NaN     NaN
3    167    Charlie A0101   E123    F123    G123    H123

我尝试过的代码如下以获得结果。但它并没有得到我想要的输出

df2=pd.pivot_table(test_shift, index=['ID', 'NAME', 'CODE'], 
columns=test_shift.groupby(['ID', 'CODE']).cumcount().add(1),
values=['TAG1'], aggfunc='sum')

Output Image

注意:对于第一次发布的错误表示抱歉,我尝试将数据框添加为代码以在视觉上为您提供帮助。但我'FAILED'。在接下来的几天里,我会努力学习这一点,并成为'Stack Overflow 的更好成员。

感谢您的帮助。

【问题讨论】:

  • stackoverflow.com/questions/20109391/… 如果您像这样创建输入数据框而不是使用图片,这将有很大帮助。
  • 请不要发布代码、数据或 Tracebacks 的图像。将其复制并粘贴为文本,然后将其格式化为代码(选择它并输入ctrl-k)...Discourage screenshots of code and/or errors
  • @ScottBoston 和二战。感谢您提供的链接,我确实检查了它们,它们确实帮助我完美地发布了我的问题。但是很抱歉我还不能做到这一点,我会继续努力的。谢谢。
  • @wwii 感谢您的建议,我尝试并发布了代码。但我无法将数据框添加到帖子中。我会在接下来的几天里再试一次。

标签: python python-3.x pandas dataframe pandas-groupby


【解决方案1】:

这里是单向:

def f(x):
    x = x.stack().to_frame(name='val')
    x = x.assign(tags='Tag'+x["val"].notna().cumsum().astype(str))
    x = (x.reset_index(level=3, drop=True)
          .set_index('tags', append=True)['val'].unstack())
    return x

df_out = (df.set_index(['ID', 'NAME','CODE'])
           .groupby(level=[0,1,2], as_index=False).apply(f)
           .reset_index().drop('level_0', axis=1))

print(df_out)

输出:

    ID     NAME   CODE  Tag1  Tag2  Tag3  Tag4
0  123     Adam   1001  A123  B123  C123  M123
1  123     Adam   1011  K123  L123   NaN   NaN
2  154      Bob   1002  D123   NaN   NaN   NaN
3  167  Charlie  A0101  E123  F123  G123  H123

【讨论】:

  • @stubbledweb1995 我们的任一解决方案对您有帮助吗?你会考虑接受其中之一吗?
  • @Scott_Boston,我能够运行代码并且它对测试数据按预期工作,我已经针对我的原始数据集运行它并且有一个我无法修复的小错误并没有完全回到它。我又试了一次,它给了我一个关键错误,所以主要是与更改代码中的“列”声明有关。我会解决的。
  • @stubbledweb1995 关键错误是列名不存在或行索引标签不存在。
  • 我能够让它工作。创建的新 TAG 列总数为 961。我想知道是否有办法将 TAG 列限制为 9。如 Tag1、Tag 2、... Tag 9。谢谢帮助。
【解决方案2】:

一种使用pd.wide_to_long 的方法将TAGS 展平,然后根据IDCODE 组映射索引,然后从IDNAME 取消堆叠并加入重复数据行和CODE

u = pd.wide_to_long(df.filter(like='TAG').reset_index(),'TAG','index','j').dropna()

idx = u.index.get_level_values(0).map(df.groupby(['ID','CODE']).ngroup()) 

u = u.set_index(pd.MultiIndex.from_arrays((idx,u.groupby(idx).cumcount()+1))).unstack()
u.columns = u.columns.map('{0[0]}{0[1]}'.format)

out = df[['ID','NAME','CODE']].drop_duplicates().reset_index(drop=True).join(u)

print(out)

    ID     NAME   CODE  TAG1  TAG2  TAG3  TAG4
0  123     Adam   1001  A123  B123  C123  M123
1  123     Adam   1011  K123  L123   NaN   NaN
2  154      Bob   1002  D123   NaN   NaN   NaN
3  167  Charlie  A0101  E123  F123  G123  H123

【讨论】:

  • 我确实运行了代码,并且运行顺利。我能够相应地修改所有必填字段。我在第 3 行遇到了 IndexError,我正在尝试找出根本原因。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-02-09
  • 2022-08-17
  • 1970-01-01
  • 2023-03-15
  • 2012-02-03
  • 1970-01-01
相关资源
最近更新 更多