超人级别 - Pandas DataFrame 由于重复而重塑
Superhuman Level - Pandas DataFrame Reshaping because of Duplicates
你喜欢只有超人才能解开的谜题吗?这是证明这种能力的最终测试。
一家公司可能在不同时间从多家银行获得不同水平的资金(种子,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')
采取预处理步骤,将资金分散到具有相同 '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
Groupby、聚合和拆分将使您接近您想要的结果
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
你喜欢只有超人才能解开的谜题吗?这是证明这种能力的最终测试。
一家公司可能在不同时间从多家银行获得不同水平的资金(种子,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')
采取预处理步骤,将资金分散到具有相同 '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
Groupby、聚合和拆分将使您接近您想要的结果
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