如何使用另一列的模式正确估算这些NaN值?

时间:2019-04-10 00:50:08

标签: python pandas jupyter-notebook missing-data imputation

我正在学习如何处理数据集中的缺失值。我有一张约有100万个条目的表。我正在尝试处理少量的缺失值。

我的数据与自行车共享系统有关,我缺少的值是起点和终点。

数据:缺少起始站,只有7个值

enter image description here

数据:缺少终点站,共有24个值

enter image description here

在两种情况下,我都想用“对面”电台的模式来填充NaN。例如,对于start_station==21,我想查看最常见的end_station,并使用它来填写我的缺失值。 例如。 df.loc[df['start_station'] == 21].end_station.mode()

我试图通过一个函数来实现这一点:

def inpute_end_station(df):
    for index, row in df.iterrows():    
        if pd.isnull(df.loc[index, 'end_station']):

            start_st = df.loc[index, 'start_station']
            mode = df.loc[df['start_station'] == start_st].end_station.mode()
            df.loc[index, 'end_station'].fillna(mode, inplace=True)

最后一行抛出AttributeError: 'numpy.float64' object has no attribute 'fillna'。相反,如果我只是使用df.loc[index, 'end_station'] = mode,我会得到ValueError: Incompatible indexer with Series

我正确地解决了吗?我知道在熊猫中修改要迭代的内容是不好的做法,因此更改start_stationend_station列并用相应的互补模式替换NaN的正确方法是什么站?

1 个答案:

答案 0 :(得分:1)

我认为,当您要像这样在熊猫中遍历一列时,最佳实践是使用apply()函数。

对于这种特殊情况,我建议采用以下方法,如下面的示例数据所示。我没有使用mode()方法的经验,因此我结合使用value_counts()方法和first_valid_index()方法来确定模式值。

# import pandas
import pandas as pd

# make a sample data
list_of_rows = [
  {'start_station': 1, 'end_station': 1},
  {'start_station': None, 'end_station': 1},
  {'start_station': 1, 'end_station': 2},
  {'start_station': 1, 'end_station': 3},
  {'start_station': 2, 'end_station': None},
  {'start_station': 2, 'end_station': 3},
  {'start_station': 2, 'end_station': 3},
]

# make a pandas data frame
df = pd.DataFrame(list_of_rows)

# define a function
def fill_NaNs_in_end_station(row):
    if pd.isnull(row['end_station']):
        start_station = row['start_station']
        return df[df['start_station']==start_station].end_station.value_counts().first_valid_index()
    return row['end_station']

# apply function to dataframe
df['end_station'] = df.apply(lambda row: fill_NaNs_in_end_station(row), axis=1)