Bandingkan dua DataFrames dan hasilkan perbedaannya secara berdampingan

162

Saya mencoba menyoroti apa yang berubah di antara dua kerangka data.

Misalkan saya memiliki dua kerangka data Python Pandas:

"StudentRoster Jan-1":
id   Name   score                    isEnrolled           Comment
111  Jack   2.17                     True                 He was late to class
112  Nick   1.11                     False                Graduated
113  Zoe    4.12                     True       

"StudentRoster Jan-2":
id   Name   score                    isEnrolled           Comment
111  Jack   2.17                     True                 He was late to class
112  Nick   1.21                     False                Graduated
113  Zoe    4.12                     False                On vacation

Tujuan saya adalah menampilkan tabel HTML yang:

  1. Identifikasi baris yang telah berubah (bisa int, float, boolean, string)
  2. Output baris dengan nilai yang sama, TUA dan BARU (idealnya ke dalam tabel HTML) sehingga konsumen dapat dengan jelas melihat apa yang berubah antara dua kerangka data:

    "StudentRoster Difference Jan-1 - Jan-2":  
    id   Name   score                    isEnrolled           Comment
    112  Nick   was 1.11| now 1.21       False                Graduated
    113  Zoe    4.12                     was True | now False was "" | now   "On   vacation"

Saya kira saya bisa melakukan perbandingan baris per baris dan kolom, tetapi apakah ada cara yang lebih mudah?

langit
sumber
Dari panda 1.1 Anda dapat dengan mudah melakukan ini dengan satu panggilan fungsi -df.compare .
cs95

Jawaban:

153

Bagian pertama mirip dengan Constantine, Anda bisa mendapatkan boolean yang barisnya kosong *:

In [21]: ne = (df1 != df2).any(1)

In [22]: ne
Out[22]:
0    False
1     True
2     True
dtype: bool

Lalu kita bisa melihat entri mana yang telah berubah:

In [23]: ne_stacked = (df1 != df2).stack()

In [24]: changed = ne_stacked[ne_stacked]

In [25]: changed.index.names = ['id', 'col']

In [26]: changed
Out[26]:
id  col
1   score         True
2   isEnrolled    True
    Comment       True
dtype: bool

Di sini entri pertama adalah indeks dan kolom kedua yang telah diubah.

In [27]: difference_locations = np.where(df1 != df2)

In [28]: changed_from = df1.values[difference_locations]

In [29]: changed_to = df2.values[difference_locations]

In [30]: pd.DataFrame({'from': changed_from, 'to': changed_to}, index=changed.index)
Out[30]:
               from           to
id col
1  score       1.11         1.21
2  isEnrolled  True        False
   Comment     None  On vacation

* Catatan: penting df1dan df2bagikan indeks yang sama di sini. Untuk mengatasi ambiguitas ini, Anda dapat memastikan Anda hanya melihat label yang dibagikan menggunakan df1.index & df2.index, tapi saya pikir saya akan meninggalkan itu sebagai latihan.

Andy Hayden
sumber
2
Saya percaya "berbagi indeks yang sama" berarti "memastikan bahwa indeks diurutkan" ... ini akan membandingkan apa pun yang pertama masuk df1ke apa pun yang pertama masuk df2, terlepas dari nilai indeks. JFYI kalau-kalau aku bukan satu-satunya orang yang ini tidak jelas. ; D Terima kasih!
dmn
12
Jika skor sama dengan nandi df1 dan df1, fungsi ini akan melaporkannya sebagai telah berubah dari nanmenjadi nan. Ini karena np.nan != np.nanpengembalian True.
James Owers
2
@ kungfujam benar. Selain itu, jika nilai yang dibandingkan adalah Tidak Ada, Anda juga akan mendapatkan perbedaan palsu
FistOfFury
Untuk memperjelas - Saya mengilustrasikan masalah dengan solusi ini dan menyediakan fungsi yang mudah digunakan yang memperbaiki masalah di bawah ini
James Owers
1
['row', 'col'] lebih disukai daripada ['id', 'col'] seperti yang diubah.index.names, karena ini bukan id, tetapi baris.
naoki fujita
87

Menyoroti perbedaan antara dua DataFrames

Dimungkinkan untuk menggunakan properti gaya DataFrame untuk menyorot warna latar belakang sel di mana ada perbedaan.

Menggunakan contoh data dari pertanyaan awal

Langkah pertama adalah menyatukan DataFrames secara horizontal dengan concatfungsi dan membedakan setiap frame dengan keysparameter:

df_all = pd.concat([df.set_index('id'), df2.set_index('id')], 
                   axis='columns', keys=['First', 'Second'])
df_all

masukkan deskripsi gambar di sini

Mungkin lebih mudah untuk menukar level kolom dan menempatkan nama kolom yang sama di samping satu sama lain:

df_final = df_all.swaplevel(axis='columns')[df.columns[1:]]
df_final

masukkan deskripsi gambar di sini

Sekarang, jauh lebih mudah untuk menemukan perbedaan dalam bingkai. Tapi, kita bisa melangkah lebih jauh dan menggunakan styleproperti untuk menyorot sel yang berbeda. Kami menetapkan fungsi khusus untuk melakukan ini yang dapat Anda lihat di bagian dokumentasi ini .

def highlight_diff(data, color='yellow'):
    attr = 'background-color: {}'.format(color)
    other = data.xs('First', axis='columns', level=-1)
    return pd.DataFrame(np.where(data.ne(other, level=0), attr, ''),
                        index=data.index, columns=data.columns)

df_final.style.apply(highlight_diff, axis=None)

masukkan deskripsi gambar di sini

Ini akan menyoroti sel-sel yang keduanya memiliki nilai yang hilang. Anda dapat mengisinya atau memberikan logika tambahan sehingga tidak disorot.

Ted Petrou
sumber
1
Apakah Anda tahu bagaimana apakah mungkin untuk mewarnai 'Pertama' dan 'Kedua' dalam warna yang berbeda?
aturegano
1
Apakah mungkin untuk memilih hanya baris yang berbeda? Dalam hal ini bagaimana cara memilih baris kedua dan ketiga tanpa memilih baris pertama (111)?
shantanuo
1
@shantanuo, ya, cukup edit metode terakhir kedf_final[(df != df2).any(1)].style.apply(highlight_diff, axis=None)
anmol
3
Implementasi ini membutuhkan waktu lebih lama ketika membandingkan kerangka data dengan 26 ribu baris dan 400 kolom. Apakah ada cara untuk mempercepatnya?
codeslord
42

Jawaban ini hanya memperpanjang @Andy Hayden, membuatnya tangguh ketika bidang numerik nan, dan membungkusnya menjadi fungsi.

import pandas as pd
import numpy as np


def diff_pd(df1, df2):
    """Identify differences between two pandas DataFrames"""
    assert (df1.columns == df2.columns).all(), \
        "DataFrame column names are different"
    if any(df1.dtypes != df2.dtypes):
        "Data Types are different, trying to convert"
        df2 = df2.astype(df1.dtypes)
    if df1.equals(df2):
        return None
    else:
        # need to account for np.nan != np.nan returning True
        diff_mask = (df1 != df2) & ~(df1.isnull() & df2.isnull())
        ne_stacked = diff_mask.stack()
        changed = ne_stacked[ne_stacked]
        changed.index.names = ['id', 'col']
        difference_locations = np.where(diff_mask)
        changed_from = df1.values[difference_locations]
        changed_to = df2.values[difference_locations]
        return pd.DataFrame({'from': changed_from, 'to': changed_to},
                            index=changed.index)

Jadi dengan data Anda (sedikit diedit untuk memiliki NaN di kolom skor):

import sys
if sys.version_info[0] < 3:
    from StringIO import StringIO
else:
    from io import StringIO

DF1 = StringIO("""id   Name   score                    isEnrolled           Comment
111  Jack   2.17                     True                 "He was late to class"
112  Nick   1.11                     False                "Graduated"
113  Zoe    NaN                     True                  " "
""")
DF2 = StringIO("""id   Name   score                    isEnrolled           Comment
111  Jack   2.17                     True                 "He was late to class"
112  Nick   1.21                     False                "Graduated"
113  Zoe    NaN                     False                "On vacation" """)
df1 = pd.read_table(DF1, sep='\s+', index_col='id')
df2 = pd.read_table(DF2, sep='\s+', index_col='id')
diff_pd(df1, df2)

Keluaran:

                from           to
id  col                          
112 score       1.11         1.21
113 isEnrolled  True        False
    Comment           On vacation
James Owers
sumber
Saya menambahkan kode untuk menangani perbedaan kecil dalam tipe data, yang akan menimbulkan kesalahan, jika Anda tidak memperhitungkannya.
Roobie Nuby
Bagaimana jika saya tidak memiliki baris identik di kedua sisi untuk dibandingkan?
Kishor kumar R
@KishorkumarR maka Anda harus meratakan baris terlebih dahulu, dengan mendeteksi baris yang ditambahkan ke kerangka data baru, dan menghapus baris dari kerangka data lama
Sabre
22
import pandas as pd
import io

texts = ['''\
id   Name   score                    isEnrolled                        Comment
111  Jack   2.17                     True                 He was late to class
112  Nick   1.11                     False                           Graduated
113  Zoe    4.12                     True       ''',

         '''\
id   Name   score                    isEnrolled                        Comment
111  Jack   2.17                     True                 He was late to class
112  Nick   1.21                     False                           Graduated
113  Zoe    4.12                     False                         On vacation''']


df1 = pd.read_fwf(io.StringIO(texts[0]), widths=[5,7,25,21,20])
df2 = pd.read_fwf(io.StringIO(texts[1]), widths=[5,7,25,21,20])
df = pd.concat([df1,df2]) 

print(df)
#     id  Name  score isEnrolled               Comment
# 0  111  Jack   2.17       True  He was late to class
# 1  112  Nick   1.11      False             Graduated
# 2  113   Zoe   4.12       True                   NaN
# 0  111  Jack   2.17       True  He was late to class
# 1  112  Nick   1.21      False             Graduated
# 2  113   Zoe   4.12      False           On vacation

df.set_index(['id', 'Name'], inplace=True)
print(df)
#           score isEnrolled               Comment
# id  Name                                        
# 111 Jack   2.17       True  He was late to class
# 112 Nick   1.11      False             Graduated
# 113 Zoe    4.12       True                   NaN
# 111 Jack   2.17       True  He was late to class
# 112 Nick   1.21      False             Graduated
# 113 Zoe    4.12      False           On vacation

def report_diff(x):
    return x[0] if x[0] == x[1] else '{} | {}'.format(*x)

changes = df.groupby(level=['id', 'Name']).agg(report_diff)
print(changes)

cetakan

                score    isEnrolled               Comment
id  Name                                                 
111 Jack         2.17          True  He was late to class
112 Nick  1.11 | 1.21         False             Graduated
113 Zoe          4.12  True | False     nan | On vacation
unutbu
sumber
3
Solusi yang sangat bagus, jauh lebih ringkas milikku!
Andy Hayden
1
@AndyHayden: Saya tidak sepenuhnya nyaman dengan solusi ini; tampaknya berfungsi hanya ketika indeks adalah indeks bertingkat. Jika saya mencoba menggunakan hanya idsebagai indeks, maka df.groupby(level='id')menimbulkan kesalahan, dan saya tidak yakin mengapa ...
unutbu
19

Saya telah menghadapi masalah ini, tetapi menemukan jawaban sebelum menemukan posting ini:

Berdasarkan jawaban unutbu, muat data Anda ...

import pandas as pd
import io

texts = ['''\
id   Name   score                    isEnrolled                       Date
111  Jack                            True              2013-05-01 12:00:00
112  Nick   1.11                     False             2013-05-12 15:05:23
     Zoe    4.12                     True                                  ''',

         '''\
id   Name   score                    isEnrolled                       Date
111  Jack   2.17                     True              2013-05-01 12:00:00
112  Nick   1.21                     False                                
     Zoe    4.12                     False             2013-05-01 12:00:00''']


df1 = pd.read_fwf(io.StringIO(texts[0]), widths=[5,7,25,17,20], parse_dates=[4])
df2 = pd.read_fwf(io.StringIO(texts[1]), widths=[5,7,25,17,20], parse_dates=[4])

... tentukan fungsi diff Anda ...

def report_diff(x):
    return x[0] if x[0] == x[1] else '{} | {}'.format(*x)

Kemudian Anda cukup menggunakan Panel untuk menyimpulkan:

my_panel = pd.Panel(dict(df1=df1,df2=df2))
print my_panel.apply(report_diff, axis=0)

#          id  Name        score    isEnrolled                       Date
#0        111  Jack   nan | 2.17          True        2013-05-01 12:00:00
#1        112  Nick  1.11 | 1.21         False  2013-05-12 15:05:23 | NaT
#2  nan | nan   Zoe         4.12  True | False  NaT | 2013-05-01 12:00:00

Omong-omong, jika Anda menggunakan IPython Notebook, Anda mungkin ingin menggunakan fungsi diff berwarna untuk memberikan warna tergantung apakah sel-selnya berbeda, sama atau nol kiri / kanan:

from IPython.display import HTML
pd.options.display.max_colwidth = 500  # You need this, otherwise pandas
#                          will limit your HTML strings to 50 characters

def report_diff(x):
    if x[0]==x[1]:
        return unicode(x[0].__str__())
    elif pd.isnull(x[0]) and pd.isnull(x[1]):
        return u'<table style="background-color:#00ff00;font-weight:bold;">'+\
            '<tr><td>%s</td></tr><tr><td>%s</td></tr></table>' % ('nan', 'nan')
    elif pd.isnull(x[0]) and ~pd.isnull(x[1]):
        return u'<table style="background-color:#ffff00;font-weight:bold;">'+\
            '<tr><td>%s</td></tr><tr><td>%s</td></tr></table>' % ('nan', x[1])
    elif ~pd.isnull(x[0]) and pd.isnull(x[1]):
        return u'<table style="background-color:#0000ff;font-weight:bold;">'+\
            '<tr><td>%s</td></tr><tr><td>%s</td></tr></table>' % (x[0],'nan')
    else:
        return u'<table style="background-color:#ff0000;font-weight:bold;">'+\
            '<tr><td>%s</td></tr><tr><td>%s</td></tr></table>' % (x[0], x[1])

HTML(my_panel.apply(report_diff, axis=0).to_html(escape=False))
journois
sumber
(Dalam Python biasa, bukan notebook iPython) apakah mungkin untuk menyertakannya my_panel = pd.Panel(dict(df1=df1,df2=df2))di dalam fungsi report_diff()? Maksud saya, apakah mungkin untuk melakukan ini: print report_diff(df1,df2)dan mendapatkan hasil yang sama dengan pernyataan cetak Anda?
edesz
pd.Panel(dict(df1=df1,df2=df2)).apply(report_diff, axis=0)- ini luar biasa !!!
MaxU
5
Panel sudah usang! Ada yang tahu cara port ini?
denfromufa
@denfromufa Saya mencoba memperbarui dalam jawaban saya: stackoverflow.com/a/49038417/7607701
Aaron N. Brock
9

Jika dua kerangka data Anda memiliki id yang sama di dalamnya, maka mencari tahu apa yang berubah sebenarnya cukup mudah. Hanya melakukan frame1 != frame2akan memberi Anda DataFrame boolean di mana masing True- masing adalah data yang telah berubah. Dari itu, Anda bisa dengan mudah mendapatkan indeks dari setiap baris yang diubah dengan melakukan changedids = frame1.index[np.any(frame1 != frame2,axis=1)].

cge
sumber
6

Pendekatan berbeda menggunakan concat dan drop_duplicates:

import sys
if sys.version_info[0] < 3:
    from StringIO import StringIO
else:
    from io import StringIO
import pandas as pd

DF1 = StringIO("""id   Name   score                    isEnrolled           Comment
111  Jack   2.17                     True                 "He was late to class"
112  Nick   1.11                     False                "Graduated"
113  Zoe    NaN                     True                  " "
""")
DF2 = StringIO("""id   Name   score                    isEnrolled           Comment
111  Jack   2.17                     True                 "He was late to class"
112  Nick   1.21                     False                "Graduated"
113  Zoe    NaN                     False                "On vacation" """)

df1 = pd.read_table(DF1, sep='\s+', index_col='id')
df2 = pd.read_table(DF2, sep='\s+', index_col='id')
#%%
dictionary = {1:df1,2:df2}
df=pd.concat(dictionary)
df.drop_duplicates(keep=False)

Keluaran:

       Name  score isEnrolled      Comment
  id                                      
1 112  Nick   1.11      False    Graduated
  113   Zoe    NaN       True             
2 112  Nick   1.21      False    Graduated
  113   Zoe    NaN      False  On vacation
jur
sumber
3

Setelah mengutak-atik jawaban @ journois, saya bisa membuatnya bekerja menggunakan MultiIndex bukan Panel karena deprication Panel .

Pertama, buat beberapa data dummy:

df1 = pd.DataFrame({
    'id': ['111', '222', '333', '444', '555'],
    'let': ['a', 'b', 'c', 'd', 'e'],
    'num': ['1', '2', '3', '4', '5']
})
df2 = pd.DataFrame({
    'id': ['111', '222', '333', '444', '666'],
    'let': ['a', 'b', 'c', 'D', 'f'],
    'num': ['1', '2', 'Three', '4', '6'],
})

Kemudian, tentukan fungsi dif Anda , dalam hal ini saya akan menggunakan yang dari jawabannya report_difftetap sama:

def report_diff(x):
    return x[0] if x[0] == x[1] else '{} | {}'.format(*x)

Lalu, saya akan menggabungkan data ke dalam kerangka data MultiIndex:

df_all = pd.concat(
    [df1.set_index('id'), df2.set_index('id')], 
    axis='columns', 
    keys=['df1', 'df2'],
    join='outer'
)
df_all = df_all.swaplevel(axis='columns')[df1.columns[1:]]

Dan akhirnya saya akan menerapkan ke report_diffbawah setiap grup kolom:

df_final.groupby(level=0, axis=1).apply(lambda frame: frame.apply(report_diff, axis=1))

Output ini:

         let        num
111        a          1
222        b          2
333        c  3 | Three
444    d | D          4
555  e | nan    5 | nan
666  nan | f    nan | 6

Dan itu saja!

Aaron N. Brock
sumber
3

Memperluas jawaban @cge, yang cukup keren untuk hasil yang lebih mudah dibaca:

a[a != b][np.any(a != b, axis=1)].join(pd.DataFrame('a<->b', index=a.index, columns=['a<=>b'])).join(
        b[a != b][np.any(a != b, axis=1)]
        ,rsuffix='_b', how='outer'
).fillna('')

Contoh demonstrasi lengkap:

import numpy as np, pandas as pd

a = pd.DataFrame(np.random.randn(7,3), columns=list('ABC'))
b = a.copy()
b.iloc[0,2] = np.nan
b.iloc[1,0] = 7
b.iloc[3,1] = 77
b.iloc[4,2] = 777

a[a != b][np.any(a != b, axis=1)].join(pd.DataFrame('a<->b', index=a.index, columns=['a<=>b'])).join(
        b[a != b][np.any(a != b, axis=1)]
        ,rsuffix='_b', how='outer'
).fillna('')
Hubbitus
sumber
1

Berikut cara lain menggunakan select dan gabung:

In [6]: # first lets create some dummy dataframes with some column(s) different
   ...: df1 = pd.DataFrame({'a': range(-5,0), 'b': range(10,15), 'c': range(20,25)})
   ...: df2 = pd.DataFrame({'a': range(-5,0), 'b': range(10,15), 'c': [20] + list(range(101,105))})


In [7]: df1
Out[7]:
   a   b   c
0 -5  10  20
1 -4  11  21
2 -3  12  22
3 -2  13  23
4 -1  14  24


In [8]: df2
Out[8]:
   a   b    c
0 -5  10   20
1 -4  11  101
2 -3  12  102
3 -2  13  103
4 -1  14  104


In [10]: # make condition over the columns you want to comapre
    ...: condition = df1['c'] != df2['c']
    ...:
    ...: # select rows from each dataframe where the condition holds
    ...: diff1 = df1[condition]
    ...: diff2 = df2[condition]


In [11]: # merge the selected rows (dataframes) with some suffixes (optional)
    ...: diff1.merge(diff2, on=['a','b'], suffixes=('_before', '_after'))
Out[11]:
   a   b  c_before  c_after
0 -4  11        21      101
1 -3  12        22      102
2 -2  13        23      103
3 -1  14        24      104

Ini hal yang sama dari tangkapan layar Jupyter:

masukkan deskripsi gambar di sini

Aziz Alto
sumber
0

panda> = 1.1: DataFrame.compare

Dengan panda 1.1, Anda pada dasarnya dapat mereplikasi keluaran Ted Petrou dengan satu panggilan fungsi. Contoh yang diambil dari dokumen:

pd.__version__
# '1.1.0.dev0+2004.g8d10bfb6f'

df1.compare(df2)

  score       isEnrolled       Comment             
   self other       self other    self        other
1  1.11  1.21        NaN   NaN     NaN          NaN
2   NaN   NaN        1.0   0.0     NaN  On vacation

Di sini, "diri" mengacu pada dataFrame LHS, sedangkan "lainnya" adalah DataFrame RHS. Secara default, nilai yang sama diganti dengan NaN sehingga Anda dapat fokus hanya pada perbedaan. Jika Anda ingin menunjukkan nilai yang sama juga, gunakan

df1.compare(df2, keep_equal=True, keep_shape=True) 

  score       isEnrolled           Comment             
   self other       self  other       self        other
1  1.11  1.21      False  False  Graduated    Graduated
2  4.12  4.12       True  False        NaN  On vacation

Anda juga dapat mengubah sumbu perbandingan menggunakan align_axis:

df1.compare(df2, align_axis='index')

         score  isEnrolled      Comment
1 self    1.11         NaN          NaN
  other   1.21         NaN          NaN
2 self     NaN         1.0          NaN
  other    NaN         0.0  On vacation

Ini membandingkan nilai baris-bijaksana, bukan kolom-bijaksana.

cs95
sumber
Catatan: panda 1.1 masih eksperimental dan hanya tersedia dengan membangun kotak pasir pengembangan .
cs95
-1

Fungsi yang menemukan perbedaan asimetris antara dua frame data diimplementasikan di bawah ini: (Berdasarkan set perbedaan untuk panda ) GIST: https://gist.github.com/oneryalcin/68cf25f536a25e65f0b3c84f9c118e03

def diff_df(df1, df2, how="left"):
    """
      Find Difference of rows for given two dataframes
      this function is not symmetric, means
            diff(x, y) != diff(y, x)
      however
            diff(x, y, how='left') == diff(y, x, how='right')

      Ref: /programming/18180763/set-difference-for-pandas/40209800#40209800
    """
    if (df1.columns != df2.columns).any():
        raise ValueError("Two dataframe columns must match")

    if df1.equals(df2):
        return None
    elif how == 'right':
        return pd.concat([df2, df1, df1]).drop_duplicates(keep=False)
    elif how == 'left':
        return pd.concat([df1, df2, df2]).drop_duplicates(keep=False)
    else:
        raise ValueError('how parameter supports only "left" or "right keywords"')

Contoh:

df1 = pd.DataFrame(d1)
Out[1]: 
                Comment  Name  isEnrolled  score
0  He was late to class  Jack        True   2.17
1             Graduated  Nick       False   1.11
2                         Zoe        True   4.12


df2 = pd.DataFrame(d2)

Out[2]: 
                Comment  Name  isEnrolled  score
0  He was late to class  Jack        True   2.17
1           On vacation   Zoe        True   4.12

diff_df(df1, df2)
Out[3]: 
     Comment  Name  isEnrolled  score
1  Graduated  Nick       False   1.11
2              Zoe        True   4.12

diff_df(df2, df1)
Out[4]: 
       Comment Name  isEnrolled  score
1  On vacation  Zoe        True   4.12

# This gives the same result as above
diff_df(df1, df2, how='right')
Out[22]: 
       Comment Name  isEnrolled  score
1  On vacation  Zoe        True   4.12
Mehmet Öner Yalçın
sumber
-1

panda impor sebagai pd impor numpy sebagai np

df = pd.read_excel ('D: \ HARISH \ DATA SCIENCE \ 1 MY Training \ SAMPEL DATA & projs \ DATA CRICKET \ DAFTAR PEMAIN IPL \ DAFTAR PEMAIN IPL \ DAFTAR PEMAIN IPL _ harish.xlsx')

df1 = srh = df [df ['TEAM']. str.contains ("SRH")] df2 = csk = df [df ['TEAM']. str.contains ("CSK")]

srh = srh.iloc [:, 0: 2] csk = csk.iloc [:, 0: 2]

csk = csk.reset_index (drop = True) csk

srh = srh.reset_index (drop = True) srh

baru = pd.concat ([srh, csk], axis = 1)

new.head ()

** JENIS PEMAIN JENIS PEMAIN

0 David Warner Batsman ... MS Dhoni Captain

1 Bhuvaneshwar Kumar Bowler ... Ravindra Jadeja All-Rounder

2 Manish Pandey Batsman ... Suresh Raina All-Rounder

3 Rashid Khan Arman Bowler ... Kedar Jadhav All-Rounder

4 Shikhar Dhawan Batsman .... Dwayne Bravo All-Rounder

HARISH TRASH
sumber
PLAYER TYPE PLAYER TYPE 0 David Warner batsman MS Dhoni Kapten 1 Bhuvaneshwar Kumar Bowler Ravindra Jadeja All-Rounder 2 Manish Pandey batsman Suresh Raina All-Rounder 3 Rashid Khan Arman Bowler Kedar Jadhav All-Rounder 4 Shikhar Dhawan batsman Dwayne Bravo All-Rounder
HARISH TRASH
Halo Harish, mohon format jawaban Anda sedikit lagi, kalau tidak cukup sulit untuk dibaca :)
Markus