将日期框架中的列值与熊猫中其他数据框架中的列值进行比较

时间:2018-12-20 11:35:56

标签: python pandas dataframe contains

我有两个数据帧,并且如果df2的“ B”列的单元格中包含df1的“ A”列中的值,我想从数据帧df2到df1插入行。如果是这种情况,那么我想在df1中的“ A”列中的匹配值下方插入行。从df2基于“关键字”列中提取需要插入的行,方法是从“关键字”列中的一个“测试”到以下“测试”具有行。

这是数据帧:

df1

    A      Keyword      B                  C
    m55                 m32\nm83\nm18      123
    m56                 m12                546
    m68
    m32
    m83
    m65
    m73                 m77\nm78           558
    m23
    m98
    m77
    m18
    m4
    m12
    m78

我有第二个数据帧(df2),将从中提取行并将其插入df1。我正在提取“关键字”列中从“测试”到“测试”的行。

df2

     Keyword      Matches            C
     test         m32\nm83\nm18      123
     something
     something
     something
     test
     something
     something
     test         m12                546
     something
     test         m77\nm78           558
     test
     something

所以,最后我需要这个:

df1

      A         Keyword      B                  C
      m55                    m32\nm83\nm18      123
      m56                    m12                546
      m68
      m32
                test         m32\nm83\nm18      123
                something
                something
                something
      m83
                test         m32\nm83\nm18      123
                something
                something
                something
     m65
     m73                    m77\nm78           558
     m23
     m98
     m77
                test         m77\nm78           558
     m18
                test         m32\nm83\nm18      123
                something
                something
                something
     m4
     m12
                test         m12                546
                something
     m78
                test         m77\nm78           558

该怎么做?

编辑:

首先,我具有此功能:

def insert_row(idx, df, df_insert):
        return df.iloc[:idx, ].append(df_insert).append(df.iloc[idx:, ]).reset_index(drop = True)

然后创建了从df2中提取行的函数:

def TestStepsReturn(df, SearchingElement):
        TestCaseList = df.index[df["Keyword"] == "test"].tolist()
        TestCaseList = np.asarray(TestCaseList)
        try:
            idx = TestCaseList[TestCaseList <= df.index[df["Matches"].str.contains(SearchingElement)][0]].max()
            idx = np.where(TestCaseList == idx)
            if idx[0][0]!=(len(TestCaseList)-1):
                return df.loc[TestCaseList[idx[0][0]]:TestCaseList[idx[0][0]+1]-1]
            return df.loc[TestCaseList[idx[0][0]]:]
        except:
            return pd.DataFrame(columns=df.columns)#return the empty data frame with the same columns names

然后创建了另一个使用TestStepsReturn的方法:

 def SerchIDs(dfFidx, df1, df2, SearchingColumn):
        for feature in dfFidx:
            feature += i 
            df_new = TestStepsReturn(df2, df1.loc[feature, SearchingColumn])# 
            df1 = insert_row(feature+1, df1, df_new)
            i += int(df_new.size/len(df_new.columns.values))
        return df

然后我有代码:

dfFidx = df1.index
df1 = SerchIDs(dfFidx, df1, df2, "A")

1 个答案:

答案 0 :(得分:1)

如果在Matches列中具有test的第一行也具有值Keyword,则解决方案有效:

#groups for get cumulative sum with comparing test value and not missing values
df2['g1'] = df2['Keyword'].eq('test').cumsum()
df2['g2'] = df2['Matches'].notna().cumsum()
#get only first groups with test
df2 = df2[df2.groupby('g2')['g1'].transform('min') == df2['g1']]
#add index value from df1 with merge
df11 = df1.reset_index()[['index','B']].dropna().rename(columns={'B':'Matches', 'index':'idx'})
df2 = df2.merge(df11, on='Matches', how='left').drop(['g1','g2'], axis=1)
df2['idx'] = df2['idx'].ffill().astype(int)
print (df2)
     Keyword        Matches      C  idx
0       test  m32\nm83\nm18  123.0    0
1  something            NaN    NaN    0
2  something            NaN    NaN    0
3  something            NaN    NaN    0
4       test            m12  546.0    1
5  something            NaN    NaN    1
6       test       m77\nm78  558.0    6
#create dictionary of DataFrames - key is index of df1
d2 = dict(tuple(df2.groupby('idx')))
#print (d2)

d = df1['B'].dropna().to_dict()
d1 = {k: df1.index[df1['A'].str.contains("|".join(v.split("\\n")))] for k, v in d.items()}

#in loop create new index and append to list
L = []
for k, v in d1.items():
    df = d2[k]
    for x in v:
        cum = np.cumsum(np.repeat(1, len(df)) / (len(df) + 1))
        df.index = np.repeat(x, len(df)) + cum
        L.append(df.copy())

#join all together
df = pd.concat([df1] + L).sort_index().reset_index(drop=True)

print (df)

      A              B      C    Keyword        Matches  idx
0   m55  m32\nm83\nm18  123.0        NaN            NaN  NaN
1   m56            m12  546.0        NaN            NaN  NaN
2   m68            NaN    NaN        NaN            NaN  NaN
3   m32            NaN    NaN        NaN            NaN  NaN
4   NaN            NaN  123.0       test  m32\nm83\nm18  0.0
5   NaN            NaN    NaN  something            NaN  0.0
6   NaN            NaN    NaN  something            NaN  0.0
7   NaN            NaN    NaN  something            NaN  0.0
8   m83            NaN    NaN        NaN            NaN  NaN
9   NaN            NaN  123.0       test  m32\nm83\nm18  0.0
10  NaN            NaN    NaN  something            NaN  0.0
11  NaN            NaN    NaN  something            NaN  0.0
12  NaN            NaN    NaN  something            NaN  0.0
13  m65            NaN    NaN        NaN            NaN  NaN
14  m73       m77\nm78  558.0        NaN            NaN  NaN
15  m23            NaN    NaN        NaN            NaN  NaN
16  m98            NaN    NaN        NaN            NaN  NaN
17  m77            NaN    NaN        NaN            NaN  NaN
18  NaN            NaN  558.0       test       m77\nm78  6.0
19  m18            NaN    NaN        NaN            NaN  NaN
20  NaN            NaN  123.0       test  m32\nm83\nm18  0.0
21  NaN            NaN    NaN  something            NaN  0.0
22  NaN            NaN    NaN  something            NaN  0.0
23  NaN            NaN    NaN  something            NaN  0.0
24   m4            NaN    NaN        NaN            NaN  NaN
25  m12            NaN    NaN        NaN            NaN  NaN
26  NaN            NaN  546.0       test            m12  1.0
27  NaN            NaN    NaN  something            NaN  1.0
28  m78            NaN    NaN        NaN            NaN  NaN
29  NaN            NaN  558.0       test       m77\nm78  6.0
相关问题