阻止groupby在python数据帧中使2个组合相同

时间:2018-11-26 19:15:50

标签: python pandas

我正在研究Kaggle(https://www.kaggle.com/manasgarg/ipl)的IPL数据集。 我想总结两个人作为一对的跑步,我已经准备好数据。 当我在dataframe列(batsman和non_striker)上尝试GROUPBY时,它正在制作同一对的2个组合。 像(a,b)和(b,a)一样-我希望它应该认为它是相同的。 由于我无法再删除行了。

import pandas as pd

df = pd.read_csv("C:\\Users\\Yash\\AppData\\Local\\Programs\\Python\\Python36-32\\Machine Learning\\IPL\\deliveries.csv")
df = df[(df["is_super_over"] != 1)]
df["pri_key"] = df["match_id"].astype(str) + "-" + df["inning"].astype(str)
openners = df[(df["over"] == 1) & (df["ball"] == 1)]
openners = openners[["pri_key", "batsman", "non_striker"]]
openners = openners.rename(columns = {"batsman":"batter1", "non_striker":"batter2"})
df = pd.merge(df, openners, on="pri_key")
df = df[["batsman", "non_striker", "batter1", "batter2", "batsman_runs"]]
df = df[((df["batsman"] == df["batter1"]) | (df["batsman"] == df["batter2"])) 
    & ((df["non_striker"] == df["batter1"]) | (df["non_striker"] == df["batter2"]))]

df1 = df.groupby(["batsman" , "non_striker"], group_keys = False)["batsman_runs"].agg("sum")
df1.nlargest(10)

Result:
batsman      non_striker
DA Warner    S Dhawan       1294
S Dhawan     DA Warner       823
RV Uthappa   G Gambhir       781
DR Smith     BB McCullum     684
CH Gayle     V Kohli         674
MEK Hussey   M Vijay         666
M Vijay      MEK Hussey      629
G Gambhir    RV Uthappa      611
BB McCullum  DR Smith        593
CH Gayle     TM Dilshan      537

而且,我想保持一对对唯一

对于那些不懂板球的人 我有一个数据框

batsman    non_striker    runs
a              b            2
a              b            3
b              a            1
c              d            6
d              c            1
d              c            4
b              a            3
e              f            1
f              e            2
f              e            6

df1 = df.groupby(["batsman" , "non_striker"], group_keys = False)["batsman_runs"].agg("sum")
    df1.nlargest(30)

output:
batsman    non_striker    runs
  a            b            5
  b            a            4
  c            d            6
  d            c            5
  e            f            1
  f            e            8

expected output:
batsman    non_striker    runs
  a            b            9
  c            d            11
  e            f            9

我该怎么办?请告知...。

3 个答案:

答案 0 :(得分:4)

您可以对击球手和非前锋进行分类,然后对数据进行分组

df[['batsman', 'non_striker']] = df[['batsman', 'non_striker']].apply(sorted, axis=1) 
df.groupby(['batsman', 'non_striker']).batsman_runs.sum().nlargest(10)

编辑:您还可以使用numpy对列进行排序,这比使用pandas排序要快

df[['batsman', 'non_striker']] = np.sort(df[['batsman', 'non_striker']],1)
df.groupby(['batsman', 'non_striker'], sort = False).batsman_runs.sum().nlargest(10).sort_index()

无论哪种方式,您都会得到

batsman         non_striker
CH Gayle        V Kohli        2650
DA Warner       S Dhawan       2242
AB de Villiers  V Kohli        2135
G Gambhir       RV Uthappa     1795
M Vijay         MEK Hussey     1302
BB McCullum     DR Smith       1277
KA Pollard      RG Sharma      1220
MEK Hussey      SK Raina       1129
AT Rayudu       RG Sharma      1121
AM Rahane       SR Watson      1118

答案 1 :(得分:1)

使用DataFrame创建新的np.sort。然后分组和求和。

import pandas as pd
import numpy as np

df1 = pd.DataFrame(np.sort(df[['batsman', 'non_striker']].values,1), 
                   index=df.index,
                   columns=['player_1', 'player_2']).assign(runs = df.runs)

df1.groupby(['player_1', 'player_2']).runs.sum()

输出:

player_1  player_2
a         b            9
c         d           11
e         f            9
Name: runs, dtype: int64

答案 2 :(得分:0)

我希望我理解你...

您可以做的事情就像将较小的值始终放在A列中,而将较大的值始终放在B列中。

import pandas as pd
import numpy as np

# generate example
values = ['a', 'b' , 'c', 'd', 'e', 'f', 'g']
df = pd.DataFrame()
df['batsman'] = np.random.choice(values, size=10)
df['no_striker'] = np.random.choice(values, size=10)

# column evaluation
df['smaller'] = df['batsman'].where(df['batsman'] < df['no_striker'], df['no_striker'])
df['greater'] = df['batsman'].where(df['batsman'] > df['no_striker'], df['no_striker'])