【问题标题】:Replace NaN values in Dataframe column by shifting columns over to the right通过将列向右移动来替换 Dataframe 列中的 NaN 值
【发布时间】:2022-10-02 17:36:32
【问题描述】:

我正在寻找将数据框中的数据拆分并转移到包含 NaN 的列中

从 pdf 读取数据并创建表格后,输出为:

   Output
   |       Summary       |  Prior Years|1|2|3|4| 5 |6|7|8|9|10|  Total  |
   |---------------------|-------------|-|-|-|-|---|-|-|-|-|--|---------|
   |Total Value 3,700,000|     110     |-|-|-|5|NaN|-|-|-|-|--|3,815,000|  
   |Total Value 320,000  |     110     |-|-|-|5|NaN|-|-|-|-|--| 435,000 |

由于 PDF 格式,读取数据会导致第一列将“总价值”和“前几年”的预期值结合起来

Expected Output
   |  Summary  |Prior Years| 1 |2|3|4|5|6|7|8|9|10|  Total  |
   |-----------|-----------|---|-|-|-|-|-|-|-|-|--|---------|
   |Total Value| 3,700,000 |110|-|-|-|5|-|-|-|-|--|3,815,000|  
   |Total Value|  320,000  |110|-|-|-|5|-|-|-|-|--| 435,000 |

包含 NaN 的 \'5\' 列之后的所有数据都符合预期

有没有办法拆分 \'Summary\' 列中的数据并让所有数据转移,直到 NaN 列被占用?

  • 是否需要多次或只为该列执行一次该操作数?
  • 目前,看起来完整的数据集只需要这样做一次
  • @DominickR,发布了一个解决方案,它有帮助吗?

标签: python pandas dataframe split


【解决方案1】:

只需通过axis = 1填充

df.ffill(axis=1)

之后,您可以轻松地将 4 列替换为 np.nan

df['4'] = df['4'].replace(5,np.nan)

【讨论】:

  • 这是一个很好的提示,但是,这只是数据的一部分。之后的某些数据在该列中没有值“5”。我希望能够将其全部转移,而不是替换
  • 在这种情况下,4 的值应该是多少?如果它们很珍贵,只需将它们隔离在一个系列中并在填充后重新添加
  • 在“摘要”列中,将 PDF 读入 DataFrame 会错误地连接值。我基本上想拆分列中包含的“总”str和int,并让所有内容向右滑动一列
【解决方案2】:

这是一种方法。基于规定的假设,即第 5 列之前的值将从左侧移动,摘要列将分为两列

# shift the values from 'Prior Years' thur column 5 to right and assign to col '1' thru '5'
df.loc[:,"1":"5"]=df.loc[:,"Prior Years":"5"].shift(axis=1)

# split the summary into text (Total Value) and the value, and assign to
# Summary and Prior Years columns

df[['Summary','Prior Years']]=df['Summary'].str.strip().str.extract(r'(\D*).*?([\d\,\.]*)' )
df

    Summary       Prior Years     1     2   3   4   5   6   7   8   9   10  Total
0   Total Value     3,700,000   110     -   -   -   5   -   -   -   -   --  3,815,000
1   Total Value       320,000   110     -   -   -   5   -   -   -   -   --  435,000

【讨论】:

  • 这是很大的帮助!谢谢你的帖子,这太棒了
【解决方案3】:

不确定所有列的 dtype 是什么,但这样的事情应该可以工作:

import pandas as pd
import numpy as np

# example dataframe (leaves off last few columns, which aren't relevant)
df = pd.DataFrame({'Summary': ['Total Value 3,700,000', 'Total Value 320,000'], 'Prior Years': [110, 110],
                   '1': ['-', '-'], '2': ['-', '-'], '3': ['-', '-'], '4': [5, 5], '5': [np.nan, np.nan],
                   '6': ['-', '-']})

# create list of column names, drop na column, and rename relevant columns (cols 1 - 5, just shift each name back by one)
columns = df.columns.to_list()
new_col_dict = {columns[i]: columns[i + 1] for i in range(1,6)}
df.drop(columns=['5'], inplace=True)
df.rename(columns=new_col_dict, inplace=True)

# split up Summary column (based on spaces)
df.loc[:, 'Prior Years'] = df.Summary.str.split(" ").apply(lambda x: x[2])
df.loc[:, 'Summary'] = df.Summary.str.split(" ").apply(lambda x: x[0]) + " " + df.Summary.str.split(" ").apply(lambda x: x[1])

# if you want the "Prior Years" column to be int type:
df.loc[:, 'Prior Years'] = df['Prior Years'].str.replace(',', '')
df.loc[:, 'Prior Years'] = df['Prior Years'].astype(int)

# re-order dataframe columns, if you care to
df = df[['Summary', 'Prior Years', '1', '2', '3', '4', '5', '6']]

【讨论】:

    【解决方案4】:

    您是否尝试过使用df.shift()

    df.shift(periods_to_be_shifted, axis = 1)
    

    在你的情况下periods_to_be_shifted = 1,试试这个:

    df.shift(1, axis = 1)
    

    【讨论】:

    • .shift 只是将所有内容移到一个上。我需要将 NaN 之后的数据保存在同一个地方。本质上,我想拆分“摘要”列中合并的数据,并将其全部滑过一次
    猜你喜欢
    • 2023-01-19
    • 2022-11-29
    • 1970-01-01
    • 2013-09-12
    • 2018-12-05
    • 1970-01-01
    • 2020-02-23
    相关资源
    最近更新 更多