Python 如何使用apply()方法从dataframe返回包含dataframe元素列表的新列?
在使用apply()方法时,有一个操作有点违反直觉。我花了几个小时的阅读来解决这个问题,就在这里 这就是我想要实现的目标 我有一个熊猫数据框,如下所示:Python 如何使用apply()方法从dataframe返回包含dataframe元素列表的新列?,python,pandas,dataframe,data-science,Python,Pandas,Dataframe,Data Science,在使用apply()方法时,有一个操作有点违反直觉。我花了几个小时的阅读来解决这个问题,就在这里 这就是我想要实现的目标 我有一个熊猫数据框,如下所示: test = pd.DataFrame({'one': [[2],['test']], 'two': [[5],[10]]}) one two 0 [2] [5] 1 [test] [10] def combine(row): result = row['one'] + row['two'] r
test = pd.DataFrame({'one': [[2],['test']], 'two': [[5],[10]]})
one two
0 [2] [5]
1 [test] [10]
def combine(row):
result = row['one'] + row['two']
return pd.Series({'result': result})
我想将每行的列添加到数据帧的原始长度,以创建一个length=的结果列表,如下所示:
def combine(row):
result = row['one'] + row['two']
return(result)
使用apply()方法在数据帧中运行时:
这不是我们想要的。我们想要的是:
result
0 [2, 5]
1 [test, 10]
编辑
我知道这个例子有更简单的解决方案。但这是一个更复杂操作的抽象。下面是一个更复杂操作的示例:
df_one:
org_id date status id
0 2 2015/02/01 True 3
1 10 2015/05/01 True 27
2 10 2015/06/01 True 18
3 10 2015/04/01 False 27
4 10 2015/03/01 True 40
df_二:
org_id date
0 12 2015/04/01
1 10 2015/02/01
2 2 2015/08/01
3 10 2015/08/01
下面是一个更复杂的操作:
def operation(row, df_one):
sel = (df_one.date < pd.Timestamp(row['date'])) & \
(df_one['org_id'] == row['org_id'])
last_changes = df_one[sel].groupby(['org_id', 'id']).last()
id_list = last_changes[last_changes.status].reset_index().id.tolist()
return (id_list)
如果采用更简单的解决方案,这是不可能的。因此,我建议在下面将操作
重新写入:
def operation(row, df_one):
sel = (df_one.date < pd.Timestamp(row['date'])) & \
(df_one['org_id'] == row['org_id'])
last_changes = df_one[sel].groupby(['org_id', 'id']).last()
id_list = last_changes[last_changes.status].reset_index().id.tolist()
return pd.Series({'id_list': id_list})
所以这个问题的答案在于
pandas.apply()
方法是如何工作的
定义时
def combine(row):
result = row['one'] + row['two']
return(result)
函数将为传入的每一行返回一个列表。如果我们将函数与.apply()
方法一起使用,这是一个问题,因为它将结果列表解释为一个系列,其中每个元素都是同一行的一列
为了解决这个问题,我们需要创建一个系列,在其中指定一个新的列名,如下所示:
test = pd.DataFrame({'one': [[2],['test']], 'two': [[5],[10]]})
one two
0 [2] [5]
1 [test] [10]
def combine(row):
result = row['one'] + row['two']
return pd.Series({'result': result})
如果我们再运行一次:
test.apply(lambda x: combine(x), axis=1)
result
0 [2, 5]
1 [test, 10]
我们会得到我们最初想要的!同样,这是因为我们强迫pandas将整个结果解释为一列。IIUC我们可以简单地将两列相加:
In [93]: test.sum(axis=1).to_frame('result')
Out[93]:
result
0 [2, 5]
1 [test, 10]
因为当我们对列表求和时:
In [94]: [2] + [5]
Out[94]: [2, 5]
它们正在连接起来…这是真的。但我的例子是一个更复杂的操作,这在你的解决方案中是不可能的。不过,我的解决方案可能是这样的。在两个数据帧中,日期列的类型是什么?例如,字符串、时间戳等。最后一行不应该是
[18,27,40]
?或[27,18,40]
,因为df_one
中的第1行似乎满足标准,并位于第2行之前。是的!你完全正确。抢手货谢谢
In [94]: [2] + [5]
Out[94]: [2, 5]