从列表中添加数据框中的列


94

我有一些像这样的数据框:

A   B   C  
0   
4
5
6
7
7
6
5

A中值可能范围仅为0到7

另外,我有一个8个元素的列表,如下所示:

List=[2,5,6,8,12,16,26,32]  //There are only 8 elements in this list

如果A列中的元素是n,我需要将List中的第n个元素插入新列,例如'D'。

如何一口气做到这一点而又不遍历整个数据框?

产生的数据框如下所示:

A   B   C   D
0           2
4           12
5           16
6           26
7           32
7           32
6           26
5           16

注意:数据框很大,迭代是最后一个选项。但是如果需要的话,我也可以将其他元素(例如dict)布置在“列表”中的元素中。


1
我认为您需要一个(较小的)玩具示例,并获得预期的结果。听起来有点模糊。
安迪·海登

11
永远不要将变量称为“列表”。任何语言。
lucid_dreamer

Answers:


50

IIUC,如果将您(不幸的是命名为)List制成ndarray,则可以简单地自然地对其进行索引。

>>> import numpy as np
>>> m = np.arange(16)*10
>>> m[df.A]
array([  0,  40,  50,  60, 150, 150, 140, 130])
>>> df["D"] = m[df.A]
>>> df
    A   B   C    D
0   0 NaN NaN    0
1   4 NaN NaN   40
2   5 NaN NaN   50
3   6 NaN NaN   60
4  15 NaN NaN  150
5  15 NaN NaN  150
6  14 NaN NaN  140
7  13 NaN NaN  130

在这里,我建立了一个新的m,但是如果您使用的话m = np.asarray(List),同样的事情也应该起作用:in中的值df.A将挑选出适当的元素m


请注意,如果您使用的是旧版本的numpy,则可能不得不改用-m[df.A.values]过去,numpy与他人的配合不佳,并且进行某些重构会pandas引起一些麻烦。现在情况有所改善。


嗨,@ DSM。我明白了您的意思,但出现了此错误: Traceback (most recent call last): File "./b.py", line 24, in <module> d["D"] = m[d.A] IndexError: unsupported iterator index
鬃毛2014年

1
@mane:urf,那是一个老numpy错误。d["D"] = m[d.A.values]对你有用吗?
DSM

277

只需直接分配列表即可:

df['new_col'] = mylist

替代
转换列表中的一系列或数组,然后分配:

se = pd.Series(mylist)
df['new_col'] = se.values

要么

df['new_col'] = np.array(mylist)

3
pykernel_launcher.py:1: SettingWithCopyWarning: A value is trying to be set on a copy of a slice from a DataFrame. Try using .loc[row_indexer,col_indexer] = value instead See the caveats in the documentation: http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-versus-copy """Entry point for launching an IPython kernel.
伊利亚·鲁辛

@sparrow会使用dtypepd.Series效果吗?我的意思是,它会将浮点数保留为浮点数,将字符串保留为字符串吗?还是列表中的元素默认为字符串?
3kstc

2
@IlyaRusin,这是一个误报,在这种情况下可以忽略。有关更多信息:stackoverflow.com/questions/20625582/…–
麻雀

1
可以简化为:df ['new_col'] = pd.Series(mylist).values
smartse

15

一种改进@sparrow的解决方案。

df为数据集和mylist与您要添加到数据框的值列表。

假设您想简单地调用新列, new_column

首先将列表分成系列:

column_values = pd.Series(mylist)

然后使用插入功能添加列。此功能的优点是让您选择要将列放置在哪个位置。在下面的示例中,我们将新列定位在左侧的第一个位置(通过设置loc = 0)

df.insert(loc=0, column='new_column', value=column_values)

如果您将df的索引更改为1,2,3以外的其他值,则此方法将不起作用...在这种情况下,您必须在两行之间添加:column_values.index = df.index
Guy的

8

首先,让我们创建您拥有的数据框,因为列B和C不相关,所以我将忽略它们。

df = pd.DataFrame({'A': [0, 4, 5, 6, 7, 7, 6,5]})

以及您想要的映射:

mapping = dict(enumerate([2,5,6,8,12,16,26,32]))

df['D'] = df['A'].map(mapping)

做完了!

print df

输出:

   A   D
0  0   2
1  4  12
2  5  16
3  6  26
4  7  32
5  7  32
6  6  26
7  5  16

1
我认为OP已经知道如何执行此操作。通过我的阅读,问题是DAand元素构成的List(“如果A列中的元素为n,则需要在新列中将List中的第n个元素插入新列,例如'D'。”)
DSM

SO已经变成某种F(*&保姆状态。感谢@DSM的评论,但是直到同行评审之后,我才能纠正该帖子。然后它被拒绝了,因为它太快了。能够对我自己的编辑进行同行评审,然后为时已晚,因为“可接受的”答案(IMHO)太差了,所以真的得到了一些元老保姆,他们的帮助不足!!!!
Phil Cooper

好吧,我不能说保姆,但是您会发现您的方法在长数组上的速度要慢一个数量级。当然,在其他方面,在np.array(List)[df.A]和之间进行选择df["A"].map(dict(enumerate(List)))主要是偏好问题。
DSM

嗨,菲尔,我只看到您的解决方案和DSM的评论,然后再也没有回过头来,因为DSM的解决方案对我来说很好。但是现在查看您的解决方案,它也可以工作。我已经在大约200k条目的数据集上运行了DSM的解决方案,它与其他所有计算一起在几秒钟内即可运行。我对python-pandas完全陌生,个人并不在寻找任何优雅或出色的东西。任何可行的都很好。但老实说,感谢您的解决方案。
2014年

1

旧问题;但我总是尝试使用最快的代码!

我有一个庞大的列表,其中包含6900万个uint64。np.array()对我来说最快。

df['hashes'] = hashes
Time spent: 17.034842014312744

df['hashes'] = pd.Series(hashes).values
Time spent: 17.141014337539673

df['key'] = np.array(hashes)
Time spent: 10.724546194076538
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.