【问题标题】:Superhuman Level - Pandas DataFrame Reshaping because of Duplicates超人级别 - Pandas DataFrame 因重复而重塑
【发布时间】:2017-10-20 03:38:19
【问题描述】:

你喜欢只有超人才能解决的谜题吗?这是证明这种能力的最终测试。

一家公司可能在不同的时间从多家银行获得不同水平的资金(种子,a)。

让我们看看数据,然后看看故事,以获得更好的画面。

import pandas as pd
data = {'id':[1,2,2,3,4],'company':['alpha','beta','beta','alpha','alpha'],'bank':['z', 'x', 'y', 'z', 'j'], 
    'rd': ['seed', 'seed', 'seed', 'a', 'a'], 'funding': [100, 200, 200, 300, 50],
   'date': ['2006-12-01', '2004-09-01', '2004-09-01', '2007-05-01', '2007-09-01']}
df = pd.DataFrame(data, columns = ['id','company', 'round', 'bank', 'funding', 'date'])
df

产量:

   id  company        rd   bank    funding        date
0   1    alpha      seed      z        100  2006-12-01
1   2     beta      seed      x        200  2004-09-01
2   2     beta      seed      y        200  2004-09-01
3   3    alpha         a      z        300  2007-05-01
4   4    alpha         a      j         50  2007-09-01

期望的输出:

   company     bank_seed   funding_seed      date_seed    bank_a  funding_a      date_a 
0    alpha             z            100     2006-12-01     [z,j]        350  2007-09-01
1     beta         [x,y]            200     2004-09-01      None       None        None

如你所见,我不是超人,但会尝试解释我的思维过程。

让我们看看公司 alpha

公司 alpha 于 2006 年底首次从 z 银行获得 100 美元的种子资金。几个月后,他们的投资者对他们的进展非常满意,因此 z 银行给了他们资金(多出 300 美元!)。然而,公司 alpha 需要更多的现金,但不得不去一些随机的瑞士银行 j 维持生计。银行 j 不情愿地多给了 50 美元。耶!他们现在从 2007 年 9 月结束的更新的“a”轮中获得了 350 美元。

公司测试版相当新。他们从两家不同的银行获得了总计 200 美元的资金。但是等等......这里没有关于他们的“a”轮的信息。没关系,我们现在将 None 并稍后与他们联系。

问题是公司 alpha 很烂,还从瑞士人那里赚钱...... 这是我在我的数据子集上工作的非工作代码 - 它不会在这里工作。

import itertools

unique_company = df.company.unique()
df_indexed = df.set_index(['company', 'rd'])
index = pd.MultiIndex.from_tuples(list(itertools.product(unique_company, list(df.rd.unique()))))
reindexed = df_indexed.reindex(index, fill_value=0)

reindexed = reindexed.unstack().applymap(lambda cell: 0 if '1970-01-01' in str(cell) else cell)

working_df = pd.DataFrame(reindexed.iloc[:, 
reindexed.columns.get_level_values(0).isin(['company', 'funding'])].to_records())

如果您知道如何解决这个问题的一部分,请继续将其放在下面。提前感谢您抽出宝贵时间查看此内容! :)

最后,如果你想看看我的代码是如何工作的。然后,执行此操作,但您会丢失很多有价值的信息...

 df = df.drop_duplicates(subset='id')
 df = df.drop_duplicates(subset='rd')

【问题讨论】:

    标签: python-2.7 pandas dataframe pivot reshape


    【解决方案1】:

    采取预处理步骤,将资金分散到具有相同 'id''date' 的记录中

    df.funding /= df.groupby(['id', 'date']).funding.transform('count')
    

    然后处理

    d1 = df.groupby(['company', 'round']).agg(
        dict(bank=lambda x: tuple(x), funding='sum', date='last')
    ).unstack().sort_index(1, 1)
    
    d1.columns = d1.columns.to_series().map('{0[0]}_{0[1]}'.format)
    
    d1
    
    
               bank funding       date    bank funding       date
    round         a       a          a    seed    seed       seed
    company                                                      
    alpha    (z, j)   350.0 2007-09-01    (z,)   100.0 2006-12-01
    beta       None     NaN        NaT  (x, y)   200.0 2004-09-01
    

    【讨论】:

    • Tuple 是个好主意,我试过 list(x) 但没用,知道为什么吗? +1
    • @A-Za-z 可哈希与不可哈希
    • 你离得太近了!测试公司的“funding_seed”列实际上是 200,因为他们从两家不同的银行收到了 200。
    • @mitchell-reynolds 那么为什么你有来自两家不同银行的 200 个呢?
    • 我不认为它是可散列与不可散列的。使用lambda x: [x.tolist()] 会让你在一个列表中卡住。
    【解决方案2】:

    Groupby、聚合和 unstack 会让你接近你想要的

    df.groupby(['company', 'round']).agg({'bank': lambda x: ','.join(x), 'funding': 'sum', 'date': 'max'}).unstack().reset_index()
    
    df.columns = ['_'.join(col).strip() for col in df.columns.values]
    

    你得到

        company_    bank_a  bank_seed   funding_a   funding_seed  date_a    date_seed
    0   alpha       z,j     z           350.0       100.0         2007-09-01 2006-12-01
    1   beta        None    x,y         NaN         400.0         None        2004-09-01
    

    【讨论】:

    • 非常非常接近! fund_seed 应该是 200,因为他们从 x 和 y 收到了 200。
    • 我不确定这是否可以处理,因为您的数据在这两个地方都显示了它。如果我们尝试从银行 x 和银行 y 中取两者中的最大值或唯一值,则会影响公司 alpha 的价值
    猜你喜欢
    • 1970-01-01
    • 2019-01-14
    • 2018-04-12
    • 2017-06-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-05
    • 2019-08-29
    相关资源
    最近更新 更多