2016-09-06 66 views
1

我是熊猫新手,我正在处理一个数据集,其中一列是带有管道(|)的字符串分隔值。现在我有一项任务,即删除此分隔字段中不符合特定条件的任何文本。熊猫数据框可以有dtype的列表吗?

我的幼稚方法是逐行迭代数据帧,并将该字段分解为列表并以此方式进行验证。然后将修改后的行写回原始数据框。看到这个metasample:

for index, row in dataframe.iterrows(): 
    fixed = [x[:29] for x in row['field'].split('|')] 
    dataframe.loc[index, 'field'] = "|".join(fixed) 

是否有更好,更重要的是更快的方式来做到这一点?

+0

在乍一看,这似乎只是对我来说,数据结构的滥用。为什么有一列是由分隔符分隔的字段列表?其他栏目是什么? –

+0

您能否提供该列或数据框的任何示例? –

+0

@ juanpa.arrivillaga好吧,这就是数据在CSV中的表现。还有其他一些列,但这是唯一一个具有列表结构的列。关键是,在我看到的原始数据中,有时候这些值中的一个是错误的......我需要将其过滤掉,然后再继续处理数据集 –

回答

2

IIUC你可以使用:

dataframe = pd.DataFrame({'field':['aasd|bbuu|cccc|ddde|e','ffff|gggg|hhhh|i|j','cccc|u|k'], 
          'G':[4,5,6]}) 

print (dataframe) 
    G     field 
0 4 aasd|bbuu|cccc|ddde|e 
1 5  ffff|gggg|hhhh|i|j 
2 6    cccc|u|k 


print (dataframe.field.str.split('|', expand=True) 
          .stack() 
          .str[:2] #change to 29 
          .groupby(level=0) 
          .apply('|'.join)) 

0 aa|bb|cc|dd|e 
1  ff|gg|hh|i|j 
2   cc|u|k 
dtype: object 

另一种解决方案通过列表理解:

dataframe['new'] = pd.Series([[x[:2] for x in y] for y in dataframe.field.str.split('|')], 
          index=dataframe.index) 
        .apply('|'.join) 
print (dataframe) 
    G     field   new 
0 4 aasd|bbuu|cccc|ddde|e aa|bb|cc|dd|e 
1 5  ffff|gggg|hhhh|i|j ff|gg|hh|i|j 
2 6    cccc|u|k   cc|u|k 

dataframe = pd.DataFrame({'field':['aasd|bbuu|cc|ddde|e','ffff|gggg|hhhh|i|j','cccc|u|k'], 
        'G':[4,5,6]}) 

print (dataframe) 
    G    field 
0 4 aasd|bbuu|cc|ddde|e 
1 5 ffff|gggg|hhhh|i|j 
2 6    cccc|u|k 

如果需要过滤器值不再作为2所有值:

s = dataframe.field.str.split('|', expand=True).stack() 
print (s) 
0 0 aasd 
    1 bbuu 
    2  cc 
    3 ddde 
    4  e 
1 0 ffff 
    1 gggg 
    2 hhhh 
    3  i 
    4  j 
2 0 cccc 
    1  u 
    2  k 
dtype: object 

dataframe['new'] = s[s.str.len() < 3].groupby(level=0).apply('|'.join) 
print (dataframe) 

    G    field new 
0 4 aasd|bbuu|cc|ddde|e cc|e 
1 5 ffff|gggg|hhhh|i|j i|j 
2 6    cccc|u|k u|k 

另一种解决方案:

dataframe['new'] = pd.Series([[x for x in y if len(x) < 3] for y in dataframe.field.str.split('|')], 
           index=dataframe.index) 
        .apply('|'.join) 
print (dataframe) 
    G    field new 
0 4 aasd|bbuu|cc|ddde|e cc|e 
1 5 ffff|gggg|hhhh|i|j i|j 
2 6    cccc|u|k u|k 
+0

谢谢,这是非常全面的工作 –