如何使用变量值填充pandas数据框中的NaN值?

时间:2018-02-22 20:19:20

标签: python pandas dataframe

我有一个数据框:

   Isolate1 Isolate2 Isolate3 Isolate4
2  NaN      NaN      AGTCTA   AGT
5  NaN      GC       NaN      NaN

并希望用破折号替换Isolate1列中的NaN值,其他列的非NaN值中的每个字母用一个破折号(如果其他列具有其他不同的值,则为最大数字),以这些类似的结尾:

  Isolate1 Isolate2 Isolate3 Isolate4
2 ------   NaN      AGTCTA   AGT
5 --       GC       NaN      NaN

我尝试了以下内容:

index_sizes_to_replace = {}
for row in df.itertuples():
    indel_sizes = []
    #0 pos is index
    for i, value in enumerate(row[1:]):
        if pd.notnull(value):
            indel_sizes.append((i, len(value)))
    max_size = max([size for i, size in indel_sizes])
    index_sizes_to_replace[row[0]]= max_size

现在我有多少破折号来代替NaN值,但不知道怎么做填充,试过这个:

for index, size in index_sizes_to_replace.iteritems():
    df.iloc[index].fillna("-"*size, inplace=True)

但没有工作,有什么建议吗?

3 个答案:

答案 0 :(得分:6)

它看起来有点难看,但它确实有这个诀窍:

import pandas as pd
import numpy as np

data = dict(Isolate1=[np.NaN,np.NaN],
            Isolate2=[np.NaN,'GC'],
            Isolate3=['AGTCTA',np.NaN],
            Isolate4=['AGT',np.NaN])

df = pd.DataFrame(data)

df['Isolate1'] = (df.drop('Isolate1',1).ffill(axis=1).bfill(axis=1)
                         .iloc[:,0].replace('.', '-', regex=True))

print(df)

返回

  Isolate1 Isolate2 Isolate3 Isolate4
2   ------      NaN   AGTCTA      AGT
5       --       GC      NaN      NaN

答案 1 :(得分:6)

试试吧:

nav-bar

原始解决方案:

import pandas as pd
import numpy as np

data = dict(Isolate1=[np.NaN,np.NaN,'A'],
            Isolate2=[np.NaN,'ABC','A'],
            Isolate3=['AGT',np.NaN,'A'],
            Isolate4=['AGTCTA',np.NaN,'A'])

df = pd.DataFrame(data)

忽略Isolate1:​​

df['Isolate1'] = df.apply(lambda x: '-' * x.str.len().max().astype(int), axis=1)

输出:

df['Isolate1'] = df.iloc[:,1:].apply(lambda x: x.str.len().max().astype(int)*'-', axis=1)

@Anton vBR编辑处理col1中不是nan。

  Isolate1 Isolate2 Isolate3 Isolate4
0   ------      NaN      AGT   AGTCTA
1      ---      ABC      NaN      NaN
2        -        A        A        A

输出:

# Create a mask
m = pd.isna(df['Isolate1'])
df.loc[m,'Isolate1'] = df[m].apply(lambda x: '-' * x.str.len().max().astype(int), axis=1)

答案 2 :(得分:4)

<强>设置

df

  Isolate1 Isolate2 Isolate3 Isolate4
0      NaN      NaN      AGT   AGTCTA
1      NaN      ABC      NaN      NaN
2        A        A        A        A

<强>解决方案
使用fillna + apply + str.__mul__

df['Isolate1'] = df.Isolate1.fillna(
       df.fillna('').applymap(len).max(1).apply('-'.__mul__)
)

  Isolate1 Isolate2 Isolate3 Isolate4
0   ------      NaN      AGT   AGTCTA
1      ---      ABC      NaN      NaN
2        A        A        A        A