用特殊字符过滤df

时间:2018-11-26 18:15:17

标签: python python-3.x pandas dataframe lambda

大家好,我的df如下:-

df = pd.DataFrame.from_records([
    {'0':'a:1','1':'b:2','2':'c:abc' },
    {'0':'a:2','1':'b:5','2':'c:afbc'}
])

enter image description here

我想将其转换为如下所示的df:-

enter image description here

我想使用值before :重命名列索引,并且列中的值应为after :

截至目前,我正在努力地进行操作,首先重命名,然后从开头删除字符:-

dff.rename(columns={'0': 'a', '1': 'b', '2': 'c',}, inplace=True)
dff['a'] = dff['a'].map(lambda x: str(x)[2:])
dff['b'] = dff['b'].map(lambda x: str(x)[2:])
dff['c'] = dff['c'].map(lambda x: str(x)[2:])

如果我有20列以上的列或lambda函数可以使用,我需要一些帮助。

P.S-原始数据帧中的0,1,2是列索引。只是为了演示,我已经将它们用作列名。

5 个答案:

答案 0 :(得分:6)

词典列表

pd.DataFrame([dict(x.split(':') for x in r) for r in df.values])

   a  b     c
0  1  2   abc
1  2  5  afbc

替代

pd.DataFrame([*df.apply(lambda r: dict(r.str.split(':').values), 1)])

回应OP的评论

  

当列名超过一个或多个这样的字符时,该代码将不起作用。仅当列名称像a,b,c而不是aa,bbbb,cccccc时才有效-ak333

考虑数据框

df = pd.DataFrame([
    {'0': 'aa:1', '1': 'bbb:2', '2': 'cccc:abc'},
    {'0': 'aa:2', '1': 'bbb:5', '2': 'cccc:afbc'}
])
df

      0      1          2
0  aa:1  bbb:2   cccc:abc
1  aa:2  bbb:5  cccc:afbc

相同的解决方案导致

pd.DataFrame([dict(x.split(':') for x in r) for r in df.values])

  aa bbb  cccc
0  1   2   abc
1  2   5  afbc

答案 1 :(得分:2)

DataFrame.apply可让您将函数应用于组成数据框的每个系列。 Series.str允许对系列元素进行向量化的字符串操作(以及其他一些东西)。

将两者放在一起:

>>> df
     0    1       2
0  a:1  b:2   c:abc
1  a:2  b:5  c:afbc
>>> 
>>> df.apply(lambda col: col.str[2:])
   0  1     2
0  1  2   abc
1  2  5  afbc

编辑:好吧,我承认这是一个丑陋的oneliner。

>>> df.apply(lambda col: col.str[2:]).rename(columns=dict(zip(df.columns, df.loc[0].str[:1])))
   a  b     c
0  1  2   abc
1  2  5  afbc

edit2:

好吧,如果':'之前的部分可以有多个字符:

>>> df.apply(lambda col: col.str.partition(':')[2]).rename(columns=dict(zip(df.columns, df.loc[0].str.partition(':')[0])))
   a  b     c
0  1  2   abc
1  2  5  afbc

我最喜欢this解决方案。

答案 2 :(得分:2)

stackstr.split一起使用,然后我们进行重塑

df.stack().str.split(':',expand=True).\
    set_index(0,append=True).\
      reset_index(level=1,drop=True)[1].\
        unstack()
Out[44]: 
0  a  b     c
0  1  2   abc
1  2  5  afbc

使用crosstab

s=df.reset_index().melt('index')
v=s.value.str.split(':')
pd.crosstab(index=s['index'],columns=v.str[0],values=v.str[1],aggfunc='first')
Out[78]: 
value  a  b     c
index            
0      1  2   abc
1      2  5  afbc

答案 3 :(得分:2)

这是使用正则表达式的一种方法,尽管我仍然会尝试以正确的格式读取数据。

df.columns = df.iloc[0].str.extract('(.*):', expand = False)
df.replace('.*:', '', regex = True, inplace = True)

a   b   c
0   1   2   abc
1   2   5   afbc

答案 4 :(得分:0)

#Create column names
df.columns=list(df[0:1].applymap(lambda x: x.split(':')[0]).iloc[0]) 

#applymap() - Apply a function to a Dataframe elementwise.
df=df.applymap(lambda x: x.split(':')[1])

df
   a  b     c
0  1  2   abc
1  2  5  afbc