【问题标题】:Pandas shift column data upon condition熊猫根据条件移动列数据
【发布时间】:2018-12-13 12:36:12
【问题描述】:

我有dataframe,看起来像这样。

    Name    Val Rating  
0   ABC     123 B + 
1   DEF     234 B + 
2   567     B-  NaN
3   GHI     890 D

但是我想通过检查(col['Name']) 到下一列(col['Val']) 并连续移动来移动数据。此外,如果发生移位,请更改行 index 值。我想要以下dataframe 作为输出。

    Name    Val Rating  
0   ABC     123 B + 
1   DEF     234 B + 
    NaN     567 B - 
2   GHI     890 D

有人知道怎么做吗?

【问题讨论】:

  • 你应该在上游处理这个问题并在输入数据框之前对其进行清理
  • 在 pandas 中总是需要索引值,那么删除它的原因是什么?
  • 您希望新的索引值是什么?
  • @aydow 但可能存在多行数据很好。在这里DEF 有两个值“234”和“567”。而且我无法访问数据框之前的输入。
  • @jezrael。如表中所示,如果存在与Name 无关的值并且具有值,则假设上面的Name 已获取多个val 数据。

标签: python pandas if-statement indexing multiple-columns


【解决方案1】:

您可以通过布尔掩码移动行:

mask = pd.to_numeric(df['Name'], errors='coerce').notnull()
df[mask] = df[mask].shift(axis=1)
print (df)
  Name  Val Rating
0  ABC  123    B +
1  DEF  234    B +
2  NaN  567     B-
3  GHI  890      D

详情:

print (pd.to_numeric(df['Name'], errors='coerce'))
0      NaN
1      NaN
2    567.0
3      NaN
Name: Name, dtype: float64

如果确实需要将索引值替换为empty 字符串,可以创建帮助程序Series 和reindex。

但不建议这样做,因为性能问题,并且该索引的某些功能可能会失败。

i = df.index[~mask]
df.index = pd.Series(range(len(i)), index=i).reindex(df.index, fill_value='')
print (df)
  Name  Val Rating
0  ABC  123    B +
1  DEF  234    B +
   NaN  567     B-
2  GHI  890      D

【讨论】:

  • @abhi1610 - 当然,尝试将列转换为数字,如果失败,创建 NaN。
  • @abhi1610 - 添加索引 - 移位值使用空字符串,因为每一行都需要设计索引。
  • 感谢您的回答。
【解决方案2】:

先定义一个函数:

import numpy as np

def f1(row):
    if not row.rating:
         row.Rating = row.val
         row.val = row.Name
         row.Name = np.NaN

然后使用pandas.DataFrame.apply:

df.apply(f1,axis=1)

【讨论】:

  • 为什么不直接使用.shift()函数而不是做你所做的事情
【解决方案3】:

使用isdigit:

df[df['Name'].str.isdigit()] = df[df['Name'].str.isdigit()].shift(axis=1)

输出:

    Name  Val Rating
0  ABC  123      B +
1  DEF  234      B +
2  NaN  567      B-
3  GHI  890      D

【讨论】:

    【解决方案4】:
    df[df['Rating'].isnull()]=df[df['Rating'].isnull()].shift(axis=1)
    print(df)
    

    输出:

      Name  Val Rating
    0  ABC  123    B +
    1  DEF  234    B +
    2  NaN  567     B-
    3  GHI  890      D
    

    编辑:

    df[df['Rating'].isnull()|df['Name'].isnull()]=df[df['Rating'].isnull()|df['Name'].isnull()].shift(axis=1)
    print(df)
    

    【讨论】:

    • 史诗。谢谢你。通过检查最后一列,我没有想到这一点。
    • 只是一个问题。如果'Name' 和Rating 中都存在NaN 怎么办?
    • @abhi1610 编辑了我的答案
    • 感谢您的回答。但是@jezrael 的答案也可以缓解索引问题,因此请考虑将他的解决方案作为答案。没有难过的感觉。
    猜你喜欢
    • 1970-01-01
    • 2023-02-02
    • 1970-01-01
    • 2023-03-21
    • 2023-02-21
    • 2019-05-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多