如果我有一个DataFrame
,其中每一行都是一个人,每列都是个人属性,那么如何才能获得一个新的DataFrame
,将每个人映射到多个结果?
我尝试使用DataFrame.apply()
这样做,这似乎是最直观的 - 但它提供了例外情况,如下例所示。添加broadcast=False
或reduce=False
无济于事。
显然,下面是一个简单的例子,但请考虑每行映射到多行的任何情况。处理这个问题的最佳方法是什么?实际上,每行可以映射到不同数量的结果。这基本上是计算一对多的关系。
示例:我有一个DataFrame
数据集,其中包含以下结构,我希望每个人都能获得即将到来的三个生日(我知道这个例子)。所以,来自:
+---+-------+------------+
| | name | birthdate |
+---+-------+------------+
| 1 | John | 1990-01-01 |
| 2 | Jane | 1957-04-03 |
| 3 | Max | 1987-02-03 |
| 4 | David | 1964-02-12 |
+---+-------+------------+
类似于:
+-------+------------+
| name | birthday |
+-------+------------+
| John | 2016-01-01 |
| John | 2017-01-01 |
| John | 2018-01-01 |
| Jane | 2016-04-03 |
| Jane | 2017-04-03 |
| Jane | 2018-04-03 |
| Max | 2016-02-03 |
| Max | 2017-02-03 |
| Max | 2018-02-03 |
| David | 2016-02-12 |
| David | 2017-02-12 |
| David | 2018-02-12 |
+-------+------------+
直觉上,我会尝试这样的事情:
def get_birthdays(person):
birthdays = []
for year in range(2016, 2019):
birthdays.append({
'name': person.name,
'birthday': person.birthdate.replace(year=year)
})
return pd.DataFrame(birthdays)
# with data as my original DataFrame
data.apply(get_birthdays, axis=1)
然而,这引起了:
ValueError: could not broadcast input array from shape (3,2) into shape (3)
During handling of the above exception, another exception occurred:
[...]
ValueError: cannot copy sequence with size 2 to array axis with dimension 3
答案 0 :(得分:5)
g++ --std=c++11 input.cpp -o output
版groupby
支持apply
作为您预期方式的返回值:
DataFrame
输出:
import pandas as pd
from datetime import datetime
df = pd.DataFrame({
'name': ['John', 'Jane', 'Max', 'David'],
'birthdate': [datetime(1990,1,1), datetime(1957,4,3), datetime(1987,2,3), datetime(1964,2,12)],
})
def get_birthdays(df_x):
d = {'name': [], 'birthday': []}
name = df_x.iloc[0]['name']
original = df_x.iloc[0]['birthdate']
for year in range(2016, 2019):
d['name'].append(name)
d['birthday'].append(original.replace(year=year))
return pd.DataFrame(d)
print df.groupby('name', group_keys=False).apply(get_birthdays).reset_index(drop=True)