根据熊猫中的两个条件处理数据框

时间:2019-05-15 08:06:06

标签: python pandas dataframe

我有一个文件要处理。看起来像:

       1       0     2      3
   0 name1 sample1 typeA1 type1
   1 name2 sample2 typeA2 type2
   2 name3 sample3 typeA3 type3
   3 name4 sample4 typeA4 type4

typeAtype列中,我得到了一些值。 “ A”,“ B”,“ C”或“ D”。

我想做什么:

需要更改列typeA和基于其值的类型。示例:

if in typeA[0] is 'D' and in type[0] = 'D'然后typeA[0] = 'Z' and type[0] = Y

if in typeA[0] is 'A' and in type[0] = 'C'然后typeA[0] = 'Z' and type[0] = Z

...等等

我写了一个if else语句并将其放入循环,代码看起来像这样:

for n in range(df.shape[0]):
    if df.iloc[n,2] == 'D' and df.iloc[n,3] == 'D':
      df.iloc[n,2] = 'Z'
      df.iloc[n,3] = 'Y'
    elif .... etc.

我有问题:

**是否存在仅使用熊猫的最简单方法?**

我找到了这样的例子:

data.loc[data.bidder == 'parakeet2004', 'bidderrate'] = 100

bidderrate's中的值为100时,作者将所有bidder col列值更改为"parakeet2004"的地方。在这种情况下,他无任何循环地更改了3行。

像我的情况一样,我试图对双语句列执行此操作(以各种方式),但只有键错误。甚至可能有更多条件吗?

如果有人可以在主要问题之外向我解释一下:在我的循环中,我是在处理数据帧副本还是在原始对象上?**

如果是副本,我应该如何处理原始对象(我不会浪费内存)?

我在SO上发现了类似的问题,但没人能解决我的问题:C

我DF的

.head():

    1           0           2   3
0   Adac44402   samp1       C   D
1   Adac44402   samp341     A   D
2   Adac44402   samp2341    A   C
3   Adac44402   samp221     C   B
4   Adac44402   samp112     C   D

2 个答案:

答案 0 :(得分:1)

我会这样

temp = pd.DataFrame({'A': ['name' + str(i) for i in range(1,5)],
                     'B': ['sample' + str(i) for i in range(1,5)],
                     'C': ['DtypeA', 'typeA', 'DtypeA', 'typeA',],
                     'D': ['typeA', 'DtypeD', 'DtypeD', 'typeD']})

就像

       A        B       C       D
0  name1  sample1  DtypeA   typeA
1  name2  sample2   typeA  DtypeD
2  name3  sample3  DtypeA  DtypeD
3  name4  sample4   typeA   typeD

首先,您需要索引满足条件的所有行(这里只有第三行满足条件)

condition = ((temp['C'].str[0] == 'D') & (temp['D'].str[0] == 'D'))

然后通过索引它们,可以更改它们的值

temp.loc[condition, 'C'] = 'Z' + temp.loc[condition, 'C'].str[1:]

给出

       A        B       C       D
0  name1  sample1  DtypeA   typeA
1  name2  sample2   typeA  DtypeD
2  name3  sample3  ZtypeA  DtypeD
3  name4  sample4   typeA   typeD

答案 1 :(得分:1)

使用旧值和新值创建帮助器DataFrame,并通过左连接的merge将它们添加到原始DataFrame中,并通过缺失值的fillna进行补充:

L = [('D','D','Z','Y'), ('A','C','Z','Z')]
cols = ['2','3']

#changed columns to strings for correct match
df.columns = df.columns.astype(str)
cols1 = [f'{a}_' for a in cols]
df1 = pd.DataFrame(L, columns=cols  + cols1)
print (df1)
   2  3 2_ 3_
0  D  D  Z  Y
1  A  C  Z  Z

df = df.merge(df1, how='left')
df[cols1] = df[cols1].fillna(df[cols].rename(columns=lambda x: x + '_'))
df = df.drop(cols, axis=1).rename(columns=lambda x: x.rstrip('_'))
print (df)
           1         0  2  3
0  Adac44402     samp1  C  D
1  Adac44402   samp341  A  D
2  Adac44402  samp2341  Z  Z
3  Adac44402   samp221  C  B
4  Adac44402   samp112  C  D

另一个想法是在boolean indexing中使用循环,并在元组中使用替换值列出原始文件:

L = [('D','D','Z','Y'), ('A','C','Z','Z')]

for x in L:
    df.loc[(df[2] == x[0]) & (df[3] == x[1]), [2,3]] = [x[2], x[3]]

print (df)
           1         0  2  3
0  Adac44402     samp1  C  D
1  Adac44402   samp341  A  D
2  Adac44402  samp2341  Z  Z
3  Adac44402   samp221  C  B
4  Adac44402   samp112  C  D