剥离 pandas 数据框并提取每个代码交换的列表

Strip pandas data frame and extract list per exchange of tickers

我正在处理一个数据框,其中包含公司名称、代码 ID 以及代码交易所 ID。抓取数据的代码工作正常。下面是数据的输出。

    Company name          (Company symbol, Company exchange)
0   Abbott Laboratories   (ABT, NYQ)
1   ABBVIE                (ABBV, NYQ)
2   ASML.AS               (ASML.AS, AMS)
3   AD.AS                 (AD.AS, AMS) 

Index(['Company name', ('Company symbol', 'Company exchange')], dtype='object')
type(df_companies)= pandas.core.frame.DataFrame

我尝试去掉多余的符号(),代码如下:

df[df_companies.columns] = df_companies.apply(lambda x: x.str.strip())
df_companies.applymap(lambda x: x.strip() if isinstance(x, str) else x)

这些代码无效,结果为 NaN。我试图转置数据框,但这也无济于事。这个想法是像这样创建 df_companies:

Company name              Company symbol  Company exchange
0   Abbott Laboratories   ABT             NYQ
1   ABBVIE                ABBV            NYQ
2   ASML.AS               ASML.AS         AMS
3   AD.AS                 AD.AS           AMS

最终的想法是为每个交易所创建一个列表,如下所示:

NYQ=['ABT', 'ABBV']
AMS=['ASMl.AS', 'AD.AS']

知道如何解决这个问题吗?

您可以使用 groupby 将另一列聚合到列表中

data = {
    "Company exchange": ["NYQ", "NYQ", "AMS", "AMS"],
    "Company Symbol" : ["ABT", "ABBV", "ASML.AS", "AD.AS"]
}

df = pd.DataFrame(data)
print(df)

输出:

df.groupby('Company exchange')['Company Symbol'].apply(list)

输出:

您可以先从 symbol/exchange 列中删除 () 括号,然后使用 expand=True:

, 上删除 Series.str.split
df[['Company Symbol','Company Exchange']] = df['(Company symbol, Company exchange)'].str.strip('()')\
                                        .str.split(',',expand=True)
df.drop('(Company symbol, Company exchange)',axis=1,inplace=True)

给出:

          Company name Company Symbol Company Exchange
0  Abbott Laboratories            ABT              NYQ
1               ABBVIE           ABBV              NYQ
2              ASML.AS        ASML.AS              AMS
3                AD.AS          AD.AS              AMS

最后:

>>> df.groupby('Company Exchange')['Company Symbol'].agg(list)

Company Exchange
 AMS    [ASML.AS, AD.AS]
 NYQ         [ABT, ABBV]

样本df:

>>> df.to_dict()

{'Company name': {0: 'Abbott Laboratories',
  1: 'ABBVIE',
  2: 'ASML.AS',
  3: 'AD.AS'},
 '(Company symbol, Company exchange)': {0: '(ABT, NYQ)',
  1: '(ABBV, NYQ)',
  2: '(ASML.AS, AMS)',
  3: '(AD.AS, AMS)'}}

请检查下面的最后一个代码:

df.columns = [str(s).replace('(','').replace(')','').replace("'",'') for s in df.columns]
df[['Company Symbol','Company Exchange']] = pd.DataFrame(df["Company symbol, Company exchange"].tolist(), index=df.index)
df.drop("Company symbol, Company exchange",axis=1,inplace=True)
df.groupby('Company Exchange')['Company Symbol'].agg(list)

来自你的 DataFrame :

>>> data = {
...    "Company name": ["Abbott Laboratories", "ABBVIE", "ASML.AS", "AD.AS"],
...    "(Company symbol, Company exchange)" : ["(ABT, NYQ)", "(ABBV, NYQ)", "(ASML.AS, AMS)", "(AD.AS, AMS)"]}
>>> df = pd.DataFrame(data)
>>> df
    Company name        (Company symbol, Company exchange)
0   Abbott Laboratories (ABT, NYQ)
1   ABBVIE              (ABBV, NYQ)
2   ASML.AS             (ASML.AS, AMS)
3   AD.AS               (AD.AS, AMS)

我们开始用 [] 替换 () 以使用列表而不是元组:

>>> df["(Company symbol, Company exchange)"] = df["(Company symbol, Company exchange)"].replace(to_replace='\(', value="[", regex=True)
>>> df["(Company symbol, Company exchange)"] = df["(Company symbol, Company exchange)"].replace(to_replace='\)', value="]", regex=True)
>>> df
    Company name        (Company symbol, Company exchange)
0   Abbott Laboratories [ABT, NYQ]
1   ABBVIE              [ABBV, NYQ]
2   ASML.AS             [ASML.AS, AMS]
3   AD.AS               [AD.AS, AMS]

现在我们可以在两个新列中“分解”括号内的数据:

>>> df[['Company symbol','Company exchange']] = pd.DataFrame(df["(Company symbol, Company exchange)"].apply(lambda x: x[1:-1].split(',')).tolist(), index= df.index)
>>> df
    Company name        (Company symbol, Company exchange)  Company symbol  Company exchange
0   Abbott Laboratories [ABT, NYQ]                          ABT             NYQ
1   ABBVIE              [ABBV, NYQ]                         ABBV            NYQ
2   ASML.AS             [ASML.AS, AMS]                      ASML.AS         AMS
3   AD.AS               [AD.AS, AMS]                        AD.AS           AMS

为了完成并获得预期的结果,我们可以使用 groupby 并获得想要的列表:

>>> df.groupby('Company exchange')['Company symbol'].apply(list)
Company exchange
 AMS    [ASML.AS, AD.AS]
 NYQ         [ABT, ABBV]
Name: Company symbol, dtype: object