Количество пропущенных записей при объединении DataFrames - PullRequest
0 голосов
/ 09 ноября 2018

В упражнении меня попросили объединить 3 кадра данных с внутренним объединением (df1 + df2 + df3 = mergedDf), затем в другом вопросе меня попросили рассказать, сколько записей я потерял при выполнении этого трехстороннего объединения .

#DataFrame1
df1 = pd.DataFrame(columns=["Goals","Medals"],data=[[5,2],[1,0],[3,1]])
df1.index = ['Argentina','Angola','Bolivia']
print(df1)
            Goals    Medals
Argentina       5         2
Angola          1         0
Bolivia         3         1

#DataFrame2
df2 = pd.DataFrame(columns=["Dates","Medals"],data=[[1,0],[2,1],[2,2])
df2.index = ['Venezuela','Africa']
print(df2)
            Dates    Medals
Venezuela       1         0
Africa          2         1
Argentina       2         2

#DataFrame3
df3 = pd.DataFrame(columns=["Players","Goals"],data=[[11,5],[11,1],[10,0]])
df3.index = ['Argentina','Australia','Belgica']
print(df3)
           Players    Goals
Argentina       11        5
Australia       11        1
Spain           10        0

#mergedDf
mergedDf = pd.merge(df1,df2,how='inner',left_index=True, right_index=True)
mergedDf = pd.merge(mergedDf,df3,how='inner',left_index=True, right_index=True)
print(mergedDF)
           Goals_X  Medals_X  Dates  Medals_Y  Players  Goals_Y
Argentina        5         2      2         2       11        2

#Calculate number of lost entries by code

Я пытался объединить все с внешним соединением, а затем вычесть mergedDf, но я не знаю, как это сделать, кто-нибудь может мне помочь? enter image description here

Ответы [ 3 ]

0 голосов
/ 09 ноября 2018

Решение с внешним соединением и индикатором параметров, последним числом строк без both в обоих столбцах индикатора a и b с суммой значений True (процессы, такие как 1 s):

mergedDf = pd.merge(df1,df2,how='outer',left_index=True, right_index=True, indicator='a')
mergedDf = pd.merge(mergedDf,df3,how='outer',left_index=True, right_index=True, indicator='b')
print(mergedDf)
           Goals_x  Medals_x  Dates  Medals_y           a  Players  Goals_y  \
Africa         NaN       NaN    2.0       1.0  right_only      NaN      NaN   
Angola         1.0       0.0    NaN       NaN   left_only      NaN      NaN   
Argentina      5.0       2.0    2.0       2.0        both     11.0      5.0   
Australia      NaN       NaN    NaN       NaN         NaN     11.0      1.0   
Belgica        NaN       NaN    NaN       NaN         NaN     10.0      0.0   
Bolivia        3.0       1.0    NaN       NaN   left_only      NaN      NaN   
Venezuela      NaN       NaN    1.0       0.0  right_only      NaN      NaN   

                    b  
Africa      left_only  
Angola      left_only  
Argentina        both  
Australia  right_only  
Belgica    right_only  
Bolivia     left_only  
Venezuela   left_only

missing = ((mergedDf['a'] != 'both') & (mergedDf['b'] != 'both')).sum()
print (missing)
6

Другое решение - использовать внутреннее объединение и sum фильтровать значения каждого индекса, которые не соответствуют mergedDf.index:

mergedDf = pd.merge(df1,df2,how='inner',left_index=True, right_index=True)
mergedDf = pd.merge(mergedDf,df3,how='inner',left_index=True, right_index=True)
vals = mergedDf.index
print (vals)
Index(['Argentina'], dtype='object')

dfs = [df1, df2, df3]
missing = sum((~x.index.isin(vals)).sum() for x in dfs)
print (missing)
6

Другое решение, если уникальные значения в каждом индексе:

dfs = [df1, df2, df3]
L = [set(x.index) for x in dfs]

#https://stackoverflow.com/a/25324329/2901002
missing = len(set.union(*L) - set.intersection(*L))
print (missing)
6
0 голосов
/ 13 ноября 2018

Я нашел простое, но эффективное решение:

Объединение 3-х фреймов данных, внутреннего и внешнего:

df1 = Df1()
df2 = Df2()
df3 = Df3()
inner = pd.merge(pd.merge(df1,df2,on='<Common column>',how='inner'),df3,on='<Common column>',how='inner')
outer = pd.merge(pd.merge(df1,df2,on='<Common column>',how='outer'),df3,on='<Common column>',how='outer')

Теперь количество пропущенных записей (строк) равно:

return (len(outer)-len(inner))
0 голосов
/ 09 ноября 2018

Вы можете передать True в indicator в слиянии

df1=pd.DataFrame({'A':[1,2,3],'B':[1,1,1]})
df2=pd.DataFrame({'A':[2,3],'B':[1,1]})
df1.merge(df2,on='A',how='inner')
Out[257]: 
   A  B_x  B_y
0  2    1    1
1  3    1    1
df1.merge(df2,on='A',how='outer',indicator =True)
Out[258]: 
   A  B_x  B_y     _merge
0  1    1  NaN  left_only
1  2    1  1.0       both
2  3    1  1.0       both
mergedf=df1.merge(df2,on='A',how='outer',indicator =True)

Тогда с value_counts вы знаете, сколько вы потеряли, когда делаете inner, так как только both сохранится, когда how='inner'

mergedf['_merge'].value_counts()
Out[260]: 
both          2
left_only     1
right_only    0
Name: _merge, dtype: int64

Для 3 df и фильтра с обоими столбцами слияния слова both

df1.merge(df2, on='A',how='outer',indicator =True).rename(columns={'_merge':'merge'}).merge(df3, on='A',how='outer',indicator =True)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...