问题
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:
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 18373Use
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 18373Convert that dataframe into a list of lists so we can iterate through each player.
team_df.values.tolist() >>>[['Player293', 1, 17656], ['Player333', 1, 18373]]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