Printing all rows in each level of MultiIndex pd.DataFrame in one row

我的梦境 提交于 2019-12-14 03:25:44

问题


I have a dataframe which was converted into a multiIndex dataframe after doing groupby() and aggregation.

In[1]:

mydata = [['Team1', 'Player1', 'idTrip13', 133], ['Team2', 'Player333', 'idTrip10', 18373],
['Team3', 'Player22', 'idTrip12', 17338899], ['Team2', 'Player293','idTrip02', 17656], 
['Team3', 'Player20', 'idTrip11', 1883], ['Team1', 'Player1', 'idTrip19', 19393]]

df = pd.DataFrame(mydata, columns = ['team', 'player', 'trips', 'time'])
df
Out[1]:
     team    player       trips      time
0   Team1   Player1     idTrip13    133
1   Team2   Player333   idTrip10    18373
2   Team3   Player22    idTrip12    17338899
3   Team2   Player293   idTrip02    17656
4   Team3   Player20    idTrip11    1883
5   Team1   Player1     idTrip19    19393

For each player on a team, find the total number of trips and total time spent traveling. This returns a multiIndex dataframe.

player_total = df.groupby(by = ['team', 'player']).agg({'time' : 'sum', 'trips' : 'count'})

player_total
Out[4]:
                 trips  time
team    player      
Team1   Player1     2   19526
Team2   Player293   1   17656
        Player333   1   18373
Team3   Player20    1   1883
        Player22    1   17338899

Desired Output: I want to print the output such that all players on a team are on the same line.

Team1   Player1 : 2 trips : 19526;
Team2   Player293 : 1 : 17656; Player333 : 1 : 18373;
Team3   Player22 : 1 trip : 17338899; Player20 : 1 trip : 1883

This question was noted as too broad so I took the liberty of splitting the pandas dataframe creation/ aggregation from the output printing.


回答1:


  1. Iterate through the 0th level (team) using groupby().

    for team, df2 in player_total.groupby(level = 0):
    

    For example at the second iteration, it will return a dataframe for Team2:

                    trips   time
    team  player              
    Team2 Player293     1  17656
          Player333     1  18373
    
  2. Use reset_index() to drop the team index column and make the player index column as part of the dataframe.

    >>>team_df = df2.reset_index(level = 0, drop = True).reset_index()
    >>>team_df
          player  trips   time
    0  Player293     1  17656
    1  Player333     1  18373
    
  3. Convert that dataframe into a list of lists so we can iterate through each player.

    team_df.values.tolist()
    >>>[['Player293', 1, 17656], ['Player333', 1, 18373]]
    
  4. When printing we have to map the integers to a string, and use the end parameter of the print function to print a semicolon instead of printing a new line at the end.

    >>>for player in team_df.values.tolist():
           print(': '.join(map(str, player)), end = '; ')
    >>>Player293: 1: 17656; Player333: 1: 18373; 
    

The full solution:

from __future__ import print_function

#iterate through each team
for team, df2 in player_total.groupby(level = 0):
    print(team, end = '\t')
    #drop the 0th level (team) and move the first level (player) as the index
    team_df = df2.reset_index(level = 0, drop = True).reset_index()
    #iterate through each player on the team and print player, trip, and time
    for player in team_df.values.tolist():
        print(': '.join(map(str, player)), end = '; ')
    #After printing all players insert a new line
    print()

Output:

Player1: 2: 19526; 
Player293: 1: 17656; Player333: 1: 18373; 
Player20: 1: 1883; Player22: 1: 17338899; 


来源:https://stackoverflow.com/questions/34539891/printing-all-rows-in-each-level-of-multiindex-pd-dataframe-in-one-row

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!