【问题标题】:Reshape column to multiple columns将列重塑为多列
【发布时间】:2017-05-05 13:11:52
【问题描述】:

我对 Python 比较陌生,但遇到了一些麻烦。我有以下数据框:

import pandas as pd
data = {'v1':('Belgium[country]', 'Antwerp[city]', 'Gent[city]', 'France[country]', 'Paris[city]', 'Marseille[city]', 'Toulouse[city]', 'Spain[country]', 'Madrid[city]')}
df = pd.DataFrame(data)
df

   v1
0  Belgium[country]
1  Antwerp[city]
2  Gent[city]
3  France[country]
4  Paris[city]
5  Marseille[city]
6  Toulouse[city]
7  Spain[country]
8  Madrid[city]

我想映射到以下格式:

   v1                v2
0  Belgium[country]  Antwerp[city]
1  Belgium[country]  Gent[city]
2  France[country]   Paris[city]
3  France[country]   Marseille[city]
4  France[country]   Toulouse[city]
5  Spain[country]    Madrid[city]

我找到了一种使用字典的方法,但由于我想保持顺序,我正在寻找一种使用列表左右的方法。

我根据索引和值本身(特别是 [国家] 和 [城市])都尝试了它,但我都失败了。非常感谢任何帮助!

【问题讨论】:

  • 在您的示例定义中,所有国家都被标记为城市。
  • 你说得对,我修好了

标签: python pandas indexing


【解决方案1】:

这将起作用:

counter = df['v1'].str.contains('country').cumsum()
result = df.groupby(counter).apply(lambda g: g[1:]).reset_index(level=1, drop=True)
result = result.rename(columns={'v1': 'v2'}).reset_index(drop=False)
result['v1'] = result['v1'].replace(df.groupby(counter).first().squeeze())

这个想法是为每个新国家添加一个递增的计数器。然后,您可以按此计数器分组以访问您需要的信息。

具体来说,第一步是只保留城市(g[1:] 为每个组 g)。然后做一些重命名和重新索引。最后,使用另一个 groupby 的结果(给出国家/地区)替换 v1 列中的值。

【讨论】:

    【解决方案2】:

    没有groupby的解决方案:

    #rename columns
    df = df.rename(columns={'v1':'v2'})
    #get counter
    counter= df.v2.str.contains('country').cumsum()
    #get mask where are changed country to city
    df.insert(0, 'v1', df.loc[counter.ne(counter.shift()), 'v2'])
    #forward filling NaN
    df.v1 = df.v1.ffill()
    #remove rows where v1 == v2
    df = df[df.v1.ne(df.v2)].reset_index(drop=True)
    
    print (df)
                     v1               v2
    0  Belgium[country]    Antwerp[city]
    1  Belgium[country]       Gent[city]
    2   France[country]      Paris[city]
    3   France[country]  Marseille[city]
    4   France[country]   Toulouse[city]
    5    Spain[country]     Madrid[city]
    

    时间安排

    In [189]: %timeit (jez(df))
    100 loops, best of 3: 2.47 ms per loop
    
    In [191]: %timeit (IanS(df1))
    100 loops, best of 3: 5.06 ms per loop
    

    计时码

    def jez(df):
        df = df.rename(columns={'v1':'v2'})
        counter= df.v2.str.contains('country').cumsum()
        df.insert(0, 'v1', df.loc[counter.ne(counter.shift()), 'v2'])
        df.v1 = df.v1.ffill()
        df = df[df.v1.ne(df.v2)].reset_index(drop=True)
    
        return (df)
    
    def IanS(df):
        counter = df['v1'].str.contains('country').cumsum()
        result = df.groupby(counter).apply(lambda g: g[1:]).reset_index(level=1, drop=True)
        result = result.rename(columns={'v1': 'v2'}).reset_index(drop=False)
        result['v1'] = result['v1'].replace(df.groupby(counter).first().squeeze())
        return (result)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-11-26
      • 2019-02-01
      • 1970-01-01
      • 2013-07-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多