Python 如何使用apply()方法从dataframe返回包含dataframe元素列表的新列?

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

在使用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})
我想将每行的列添加到数据帧的原始长度,以创建一个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]