从几列中过滤数据

时间:2018-12-15 22:32:20

标签: python pandas dataframe

我有这个数据框:

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)

我有所有国家/地区的清单,在它们旁边是TrueFalse
因此它实际上不过滤任何内容。

还有:

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'

我考虑过的另一个问题是,由于错误而未能进入此步骤:

应如何显示分数:浮点数?还有其他东西吗?

我还看着hereherehereherehere

我发现以下相关功能:

where()mask()query()isin()all()等。

但这似乎是一个棘手的问题,上述链接中的哪一个都没有真正帮助我解决问题。

非常感谢。

3 个答案:

答案 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 answerthis answer之后,我仍然感到困惑,并且不知道以下哪一项:

index_col=0index_col=Falseindex_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()