2016-03-15 151 views
2

鉴于以下数据帧:熊猫条件地串联

df = pd.DataFrame({'foo':['[a]','[b'], 
        'bar':['[a','[b]']}) 
df 
    bar foo 
0 [a] [a 
1 [b [b] 

欲右括号“]”添加到那些其中值缺乏它们的细胞。 期望的结果是:

bar foo 
0 [a] [a] 
1 [b] [b] 

不过,我不确定有多少列将有,所以我想将它应用到整个数据帧。

我开始了这一点,但没有运气:

df2 = df(lambda x: str(x)+"]" if (len(x)<3)) 

提前感谢!

更新: 我实际上用一个看起来像这样的表工作:

0  1  2 
0 b [r] None None 
1 c [d d [r] f[d] 
2 g [r] h [d] None 
3 m [r p [d] None 
4 b [r] n [d 
5 m [d] a [r] None 
+0

感谢您的好评。我注意到,当一些单元格包含“无”或是空白时,我得到以下错误:IndexError:字符串索引超出范围。我应该在原始问题中列出这张表,但我认为这不重要。我会在上面张贴它。 –

回答

2

您可以通过列使用循环,因为string功能与Series工作。通过~使用indexing with strloc

print df 
    bar foo 
0 [a [a] 
1 [b] [b 

for cols in df.columns: 
    #print df[cols].str[-1] != ']' 
    df.loc[df[cols].str[-1] != ']', cols] = df[cols] + ']' 
print df 
    bar foo 
0 [a] [a] 
1 [b] [b] 

或者使用contains与反转掩码:

for cols in df.columns: 
    df.loc[~df[cols].str[-1].str.contains(']'), cols] = df[cols] + ']' 
print df 
    bar foo 
0 [a] [a] 
1 [b] [b]   

感谢您的root使用endswith评论:

for cols in df.columns: 
    df.loc[~df[cols].str.endswith(']'), cols] = df[cols] + ']' 
print df 

编辑:

如果有空stringsnone值:

print df 
0 [a  
1 [b] [b 
2 [a None 

for col in df.columns: 
    df.loc[~df[col].str.endswith(']').replace({np.nan: False}), col] = df[col] + ']' 
    df[col] = df[col].replace({']': ''}) 

print df 
    bar foo 
0 [a]  
1 [b] [b] 
2 [a] NaN 
+1

我认为使用'endswith'可能比'contains'更简单。例如。 '〜df [cols] .str.endswith(']')' – root

+0

对不起,我应该在这里发表评论;如果有一个空白的单元格呢?这似乎给我一个索引错误:字符串索引超出范围。我试过这个但没有骰子:df2.loc [(〜df2 [cols] .str [-1] .str.endswith(']'))&(〜pd.isnull [cols]),cols] = df2 [cols ] +']' –

+0

如果有'空'字符串,可以输出'NaN'? – jezrael

1

让我们来了解DataFrame.applymap()功能

df.applymap(func_reference) 

上面的一行将拜会每个单元的func_referencedf。现在我们可以设计我们的func_reference

def my_filter(cell): 
    if cell[-1] == ']': 
     return cell 
    return cell + ']' 

filtered_df = df.applymap(my_filter) 

这可能不是最有效的方法,但我认为它很可读。