使用非传统方法条件填充Pandas数据框中的缺失值

时间:2018-04-24 00:37:12

标签: python pandas

TLDR; 如何改进我的代码并使其更加pythonic?

您好,

我们在教程中给出的一个有趣的挑战如下: “数据框中有X个缺失条目,其中包含相关代码,但代码旁边有一个'空白'条目。这是数据框中的随机出现。使用您对熊猫的了解,将每个缺少的'空白'条目映射到相关代码。“

所以这看起来如下:

|code| |name|
001     Australia
002     London
...
001    <blank>

我使用的方法如下:

遍历整个数据框并识别带有空格“”的区域。通过将关联的正确代码(已订购)复制到数据框来替换所有空白。

code_names = [ "",
    'Economic management', 
    'Public sector governance', 
    'Rule of law',
    'Financial and private sector development', 
    'Trade and integration', 
    'Social protection and risk management', 
    'Social dev/gender/inclusion', 
    'Human development', 
    'Urban development', 
    'Rural development', 
    'Environment and natural resources management'
]

df_copy = df_.copy()

# Looks through each code name, and if it is empty, stores the proper name in its place
for x in range(len(df_copy.mjtheme_namecode)):
    for y in range(len(df_copy.mjtheme_namecode[x])):
        if(df_copy.mjtheme_namecode[x][y]['name'] == ""):
            df_copy.mjtheme_namecode[x][y]['name'] = code_names[int(df_copy.mjtheme_namecode[x][y]['code'])]

limit = 25
counter = 0

for x in range(len(df_copy.mjtheme_namecode)):
    for y in range(len(df_copy.mjtheme_namecode[x])):
        print(df_copy.mjtheme_namecode[x][y])
        counter += 1
    if(counter >= limit):
        break

虽然上述方法有效 - 是否有一种更好,更pythonic的方式来实现我追求的目标?我觉得我使用的方法非常笨重,因为我的技能不是很发达。

谢谢!

1 个答案:

答案 0 :(得分:0)

方法1:

执行此操作的一种方法是将所有""空白替换为NaN,按codename对数据进行排序,然后使用fillna(method='ffill')

从这开始:

>>> df
   code       name
0     1  Australia
1     2     London
2     1           

您可以应用以下内容:

new_df = (df.replace({'name':{'':np.nan}})
          .sort_values(['code', 'name'])
          .fillna(method='ffill')
          .sort_index())

>>> new_df
   code       name
0     1  Australia
1     2     London
2     1  Australia

方法2:

这更复杂,但也会有效: 使用groupbyfirstsqeeze,您可以创建pd.Series以将代码映射到非空白名称,并使用.map映射该系列到code栏:

df['name'] = (df['code']
              .map(
                  df.replace({'name':{'':np.nan}})
                  .sort_values(['code', 'name'])
                  .groupby('code')
                  .first()
                  .squeeze()
              ))

>>> df
   code       name
0     1  Australia
1     2     London
2     1  Australia

说明:此创建的pd.Series地图如下所示:

code
1    Australia
2       London

它的工作原理是因为它获取了每个代码的第一个实例(通过groupby),以NaN s最后的方式排序。因此,只要每个代码与名称相关联,此方法就可以工作。