我有这个数据框:
import pandas as pd
df = pd.read_csv('olympics.csv', index_col=0, skiprows=1)
for col in df.columns:
if col[:2]=='01':
df.rename(columns={col:'Gold'+col[4:]}, inplace=True)
if col[:2]=='02':
df.rename(columns={col:'Silver'+col[4:]}, inplace=True)
if col[:2]=='03':
df.rename(columns={col:'Bronze'+col[4:]}, inplace=True)
if col[:1]=='№':
df.rename(columns={col:'#'+col[1:]}, inplace=True)
names_ids = df.index.str.split('\s\(') # split the index by '('
df.index = names_ids.str[0] # the [0] element is the country name (new index)
df['ID'] = names_ids.str[1].str[:3] # the [1] element is the abbreviation or ID (take first 3 characters from that)
df = df.drop('Totals')
df.head()
olympics.csv
文件实际上是this list。
以下是DataFrame(前五个国家)的图片:
以下是前十个国家/地区的代码:
{'# Summer': {'Afghanistan': 13,
'Algeria': 12,
'Argentina': 23,
'Armenia': 5,
'Australasia': 2,
'Australia': 25,
'Austria': 26,
'Azerbaijan': 5,
'Bahamas': 15,
'Bahrain': 8},
'Gold': {'Afghanistan': 0,
'Algeria': 5,
'Argentina': 18,
'Armenia': 1,
'Australasia': 3,
'Australia': 139,
'Austria': 18,
'Azerbaijan': 6,
'Bahamas': 5,
'Bahrain': 0},
'Silver': {'Afghanistan': 0,
'Algeria': 2,
'Argentina': 24,
'Armenia': 2,
'Australasia': 4,
'Australia': 152,
'Austria': 33,
'Azerbaijan': 5,
'Bahamas': 2,
'Bahrain': 0},
'Bronze': {'Afghanistan': 2,
'Algeria': 8,
'Argentina': 28,
'Armenia': 9,
'Australasia': 5,
'Australia': 177,
'Austria': 35,
'Azerbaijan': 15,
'Bahamas': 5,
'Bahrain': 1},
'Total': {'Afghanistan': 2,
'Algeria': 15,
'Argentina': 70,
'Armenia': 12,
'Australasia': 12,
'Australia': 468,
'Austria': 86,
'Azerbaijan': 26,
'Bahamas': 12,
'Bahrain': 1},
'# Winter': {'Afghanistan': 0,
'Algeria': 3,
'Argentina': 18,
'Armenia': 6,
'Australasia': 0,
'Australia': 18,
'Austria': 22,
'Azerbaijan': 5,
'Bahamas': 0,
'Bahrain': 0},
'Gold.1': {'Afghanistan': 0,
'Algeria': 0,
'Argentina': 0,
'Armenia': 0,
'Australasia': 0,
'Australia': 5,
'Austria': 59,
'Azerbaijan': 0,
'Bahamas': 0,
'Bahrain': 0},
'Silver.1': {'Afghanistan': 0,
'Algeria': 0,
'Argentina': 0,
'Armenia': 0,
'Australasia': 0,
'Australia': 3,
'Austria': 78,
'Azerbaijan': 0,
'Bahamas': 0,
'Bahrain': 0},
'Bronze.1': {'Afghanistan': 0,
'Algeria': 0,
'Argentina': 0,
'Armenia': 0,
'Australasia': 0,
'Australia': 4,
'Austria': 81,
'Azerbaijan': 0,
'Bahamas': 0,
'Bahrain': 0},
'Total.1': {'Afghanistan': 0,
'Algeria': 0,
'Argentina': 0,
'Armenia': 0,
'Australasia': 0,
'Australia': 12,
'Austria': 218,
'Azerbaijan': 0,
'Bahamas': 0,
'Bahrain': 0},
'# Games': {'Afghanistan': 13,
'Algeria': 15,
'Argentina': 41,
'Armenia': 11,
'Australasia': 2,
'Australia': 43,
'Austria': 48,
'Azerbaijan': 10,
'Bahamas': 15,
'Bahrain': 8},
'Gold.2': {'Afghanistan': 0,
'Algeria': 5,
'Argentina': 18,
'Armenia': 1,
'Australasia': 3,
'Australia': 144,
'Austria': 77,
'Azerbaijan': 6,
'Bahamas': 5,
'Bahrain': 0},
'Silver.2': {'Afghanistan': 0,
'Algeria': 2,
'Argentina': 24,
'Armenia': 2,
'Australasia': 4,
'Australia': 155,
'Austria': 111,
'Azerbaijan': 5,
'Bahamas': 2,
'Bahrain': 0},
'Bronze.2': {'Afghanistan': 2,
'Algeria': 8,
'Argentina': 28,
'Armenia': 9,
'Australasia': 5,
'Australia': 181,
'Austria': 116,
'Azerbaijan': 15,
'Bahamas': 5,
'Bahrain': 1},
'Combined total': {'Afghanistan': 2,
'Algeria': 15,
'Argentina': 70,
'Armenia': 12,
'Australasia': 12,
'Australia': 480,
'Austria': 304,
'Azerbaijan': 26,
'Bahamas': 12,
'Bahrain': 1},
'ID': {'Afghanistan': 'AFG',
'Algeria': 'ALG',
'Argentina': 'ARG',
'Armenia': 'ARM',
'Australasia': 'ANZ',
'Australia': 'AUS',
'Austria': 'AUT',
'Azerbaijan': 'AZE',
'Bahamas': 'BAH',
'Bahrain': 'BRN'}}
Gold
的意思是:夏季金牌的数量。Gold.1
的意思是:冬天金牌的数量。Gold.2
的意思是: ALL 金牌的数量。问题是:
相对于总金牌数量,哪个国家的夏季金牌数量和冬季金牌数量之间的差异最大?
更清晰地说:
(这意味着:找到拥有夏季金牌数量最多,冬季金牌数量最少和金牌总数最少的国家)。
仅包括在夏季和冬季均赢得至少1金的国家/地区。
此函数应返回单个字符串值。
我的解决方案:
我尝试通过两个步骤解决此问题:
第一:
仅过滤获得金牌的国家(夏季和冬季)。
这是我到达的最接近的代码:
df[(df['Gold'] > 0) & (df['Gold.1'] > 0)]
但是它返回一个 DataFrame ,而不是一个 list 。
尝试此代码:
(df['Gold'] > 0) & (df['Gold.1'] > 0)
我有所有国家/地区的清单,在它们旁边是True
或False
。
因此它实际上不过滤任何内容。
还有:
print(df.loc[df['Gold'] == True])
这似乎给出了错误的答案。
这就是我所拥有的:
(请注意,例如,该列表不包含美国)。
第二:
找到分数的最大值:
好吧,代码:
(df['Gold'] - df['Gold.1']).idxmax()
和
df['Gold.2'].idxmin()
解释得很好,
但是:
(df['Gold'] - df['Gold.1']).idxmax() & df['Gold.2'].idxmin()
给我一个错误:
TypeError: unsupported operand type(s) for &: 'str' and 'str'
我也尝试过以下代码:
df.loc[df['Gold'] > 0 & (df['Gold'] - df['Gold.1']).idxmax() & df['Gold.2'].idxmin()]
这给了我同样的错误:
TypeError: unsupported operand type(s) for &: 'int' and 'str'
我考虑过的另一个问题是,由于错误而未能进入此步骤:
应如何显示分数:浮点数?还有其他东西吗?
我发现以下相关功能:
where()
,mask()
,query()
,isin()
,all()
等。
但这似乎是一个棘手的问题,上述链接中的哪一个都没有真正帮助我解决问题。
非常感谢。
答案 0 :(得分:0)
根据您提供的(第一张)图片,我会做
# Rename the columns to make more sense to me
df.columns = ['S-Participation', 'S-Gold', 'S-Silver', 'S-Bronze', 'S-Total', 'W-Participation', 'W-Gold', 'W-Silver', 'W-Bronze', 'W-Total', 'Combined-Participation', 'Combined-Gold', 'Combined-Silver', 'Combined-Bronze', 'Combined-Total', 'ID']
# Get the rows with medals in both
df = df.loc[(df['S-Gold'] > 0) & (df['W-Gold'] > 0), :]
# Calculate difference
df['Diff-Gold'] = (df['S-Gold'] - df['W-Gold']).abs() / (df['S-Gold'] + df['W-Gold'])
# Sort by difference and then take the top value
df = df.sort_values('Diff-Gold', ascending=False)
df['ID'].iloc[0]
我不会测试它,因为没有数据可以这样做。
答案 1 :(得分:0)
我正在尝试查看上面建议的答案是否正确。
首先,我试图将代码分成每个步骤,从而使分析和理解变得更加容易。
第一代码行,即:
# Rename the columns to make more sense to me
df.columns = ['S-Participation', 'S-Gold', 'S-Silver', 'S-Bronze', 'S-Total', 'W-Participation', 'W-Gold', 'W-Silver', 'W-Bronze', 'W-Total', 'Combined-Participation', 'Combined-Gold', 'Combined-Silver', 'Combined-Bronze', 'Combined-Total', 'ID']
给我一个错误:
Length mismatch: Expected axis has 17 elements, new values have 16 elements
第一个问题:
出现此错误,我不明白为什么解释器继续解释其余代码...
第二个问题:
在this answer和this answer之后,我仍然感到困惑,并且不知道以下哪一项:
index_col=0
,index_col=False
或index_col=None
可能会解决上面代码行中的错误,以及如何在其中嵌入正确的命令(三个)。
两个问题的答案将不胜感激。
谢谢!
答案 2 :(得分:0)
import pandas as pd
import numpy as np
df = pd.read_csv('olympics.csv', index_col=0, skiprows=1)
for col in df.columns:
if col[:2]=='01':
df.rename(columns={col:'Gold'+col[4:]}, inplace=True)
if col[:2]=='02':
df.rename(columns={col:'Silver'+col[4:]}, inplace=True)
if col[:2]=='03':
df.rename(columns={col:'Bronze'+col[4:]}, inplace=True)
if col[:1]=='№':
df.rename(columns={col:'#'+col[1:]}, inplace=True)
names_ids = df.index.str.split('\s\(') # split the index by '('
df.index = names_ids.str[0] # the [0] element is the country name (new index)
df['ID'] = names_ids.str[1].str[:3] # the [1] element is the abbreviation or ID (take first 3 characters from that)
df = df.drop('Totals')
df.head()
def answer_one():
Diff = df[(df['Gold'] > 0) & (df['Gold.1'] > 0)]
return ((Diff['Gold'] - Diff['Gold.1']) / Diff['Gold.2']).idxmax()
answer_one()