处理数据框以实现多个目标

时间:2019-07-17 16:12:54

标签: python pandas dataframe

df看起来像这样

s = {0: [np.nan, 'a' ,'b', 'c', 'd'], 
    1: ['A', '8(F)', '6', '8', '4(F)'], 
    2: ['B', '1', '6', '8(F)', '3(F)'],
    3: ['C', '1', '8', '8', '1'],
    4: ['D', '1', '2(F)', '6', '8']}

df = pd.DataFrame(data=s)

     0     1     2    3     4
0  NaN     A     B    C     D
1    a  8(F)     1    1     1
2    b     6     6    8  2(F)
3    c     8  8(F)    8     6
4    d  4(F)  3(F)    1     8

首先,我要选择(F)数据并在新数据框上列出

  Value
0  8(F)
1  4(F)     
2  8(F)     
3  3(F)     
4  2(F)

第二,我要添加大写字母

  Value  Upper
0  8(F)   A    
1  4(F)   A 
2  8(F)   B 
3  3(F)   B 
4  2(F)   D

以及小写字母

  Value  Upper Lower
0  8(F)   A     a
1  4(F)   A     d
2  8(F)   B     c
3  3(F)   B     d
4  2(F)   D     b

最后,我想根据下表对每一行进行评论

  Upper Lower  Num
0   A     a     9
1   A     b     1
2   A     c     2
3   A     d     3
4   B     a     0
5   B     b     4
6   B     c     8
7   B     d     3
8   C     a     4
9   C     b     8
10  C     c     4
11  C     d     6
12  D     a     4 
13  D     b     1 
14  D     c     4 
15  D     d     3 

我将通过比较ValueNum来注释每一行

  Value  Upper Lower Comment
0  8(F)   A     a    smaller   
1  4(F)   A     d    bigger 
2  8(F)   B     c    equal
3  4(F)   B     d    equal
4  2(F)   D     b    smaller

请注意,我不想在代码中使用任何for循环。 希望有人可以帮助我解决这个烦人的问题。

3 个答案:

答案 0 :(得分:3)

这是使用merge并与df1进行比较的一种方法

df=df.astype(str)
s=df[df.applymap(lambda x : '(F)' in x)].stack().rename_axis(['Lower','Upper']).reset_index()

s['Comment']=np.sign((s[0].str.split('(').str[0].astype(int)-s.merge(df1).Num)).map({-1:'lt',0:'eq',1:'gt'})
s
Out[753]: 
  Lower Upper     0 Comment
0     a     A  8(F)      lt
1     b     D  2(F)      gt
2     c     B  8(F)      eq
3     d     A  4(F)      gt
4     d     B  3(F)      eq

答案 1 :(得分:1)

numpy.core.defchararray及更多

from numpy.core.defchararray import find

v = df.to_numpy().astype(str)
m = find(v.T[1:, 1:], '(F)') >= 0
i, j = np.where(m)

d = pd.DataFrame({
    'Value': v[1:, 1:][j, i],
    'Upper': v[0, 1:][i],
    'Lower': v[1:, 0][j]
}).merge(df1)

labels = np.array(['equal', 'bigger', 'smaller'])
d.assign(Comment=labels[np.sign(d.Value.str[:-3].astype(int) - d.Num)])

  Value Upper Lower  Num  Comment
0  8(F)     A     a    9  smaller
1  4(F)     A     d    3   bigger
2  8(F)     B     c    8    equal
3  3(F)     B     d    3    equal
4  2(F)     D     b    1   bigger

答案 2 :(得分:0)

使用以下代码: 其中dfdf1是您给定的数据帧:

df2 = pd.merge(df, df1, how='inner', left_on=['Upper', 'Lower'], right_on=['Upper', 'Lower'])

df2['Comment'] = df2.apply(lambda x: np.where(x['Num'] > int(x['Value'][0]), 'bigger', 'smaller') , 1)

EDIT1:

在下面使用以在上面使用df:

l = []
df = df.replace("[0-9A-Za-z]$", np.nan, regex=True)
for col in range(len(df)):
     l = l + df2.iloc[:,col].dropna().values.tolist()

df = pd.Series(df)