首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >根据现有列向Dataframe添加多行和单列

根据现有列向Dataframe添加多行和单列
EN

Stack Overflow用户
提问于 2019-02-11 08:26:31
回答 4查看 1.2K关注 0票数 2

我想要添加新行,并根据现有列添加一个新列。例如,假设我跟踪了Dataframe:

代码语言:javascript
复制
   A          B
   1          a
   2          b
   3          c
   4          b

以及以唯一列B值作为键的字典。每个键与一个值列表相关联。这些值用于新的行和列:{a: [x, y, z], b: [x, w, r], c: [x, q]}

转换将产生以下Dataframe:

代码语言:javascript
复制
   A          C          
   1          x
   1          y
   1          z
   2          x
   2          w
   2          r
   3          x
   3          q
   4          x
   4          w
   4          r

我知道如何添加一个新列,但我仍然试图复制行。解决这个问题最有效的方法是什么?我是更新现有的Dataframe还是创建一个新的?

更新

该操作将使用Dask对大型数据帧(20 milion+行)使用。

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2019-02-11 08:38:01

我建议用mapnp.repeatchain.from_iterable创建新的

代码语言:javascript
复制
d = {'a': ['x', 'y', 'z'], 'b': ['x', 'w', 'r'], 'c': ['x', 'q']}

s = df['B'].map(d)
lens = [len(x) for x in s]

from itertools import chain

df = pd.DataFrame({
    'A' : df['A'].values.repeat(lens),
    'C' : list(chain.from_iterable(s.values.tolist()))
})
print (df)
    A  C
0   1  x
1   1  y
2   1  z
3   2  x
4   2  w
5   2  r
6   3  x
7   3  q
8   4  x
9   4  w
10  4  r

如果字典的某些值不匹配,则使用更通用的解决方案:

第一个解决方案返回错误,因为map返回丢失的值:

TypeError:类型为'NoneType‘的对象没有len()

代码语言:javascript
复制
print (df)
   A  B
0  1  d <- change data
1  2  b
2  3  c
3  4  b

d = {'a': ['x', 'y', 'z'], 'b': ['x', 'w', 'r'], 'c': ['x', 'q']}

s = [d.get(x, [x]) for x in df['B']]
print (s)
[['d'], ['x', 'w', 'r'], ['x', 'q'], ['x', 'w', 'r']]

lens = [len(x) for x in s]

from itertools import chain

df = pd.DataFrame({
    'A' : df['A'].values.repeat(lens),
    'B' : list(chain.from_iterable(s))
})
print (df)
   A  B
0  1  d
1  2  x
2  2  w
3  2  r
4  3  x
5  3  q
6  4  x
7  4  w
8  4  r

因为使用dask,另一个解决方案应该是:

代码语言:javascript
复制
d = {'a': ['x', 'y', 'z'], 'b': ['x', 'w', 'r'], 'c': ['x', 'q']}
df1 = pd.DataFrame([(k, y) for k, v in d.items() for y in v], columns=['B','C'])
print (df1)
   B  C
0  a  x
1  a  y
2  a  z
3  b  x
4  b  w
5  b  r
6  c  x
7  c  q

df = df.merge(df1, on='B', how='left')
print (df)
    A  B  C
0   1  a  x
1   1  a  y
2   1  a  z
3   2  b  x
4   2  b  w
5   2  b  r
6   3  c  x
7   3  c  q
8   4  b  x
9   4  b  w
10  4  b  r
票数 2
EN

Stack Overflow用户

发布于 2019-02-11 09:19:34

您可以使用名为DataFrame和C的列将dict转换为

代码语言:javascript
复制
df2 = pd.DataFrame.from_dict(d, orient='index').stack().reset_index().iloc[:, [0, -1]]
df2.columns = ['B', 'C']

将此新df2与初始df合并,并选择您希望拥有的数据:

代码语言:javascript
复制
df.merge(df2, on='B').set_index('A')['C'].sort_index()
票数 2
EN

Stack Overflow用户

发布于 2019-02-11 09:46:39

使用sum()map()的另一种方法

代码语言:javascript
复制
d = {'a': ['x', 'y', 'z'], 'b': ['x', 'w', 'r'], 'c': ['x', 'q']}
df_new= pd.DataFrame({'A': np.repeat(df.A,df.B.map(d).apply(len)).\
              reset_index(drop=True),'B':df.B.map(d).sum()})

或者更好地使用运算符reduce (对于大型数据文件):

代码语言:javascript
复制
import functools,operator
df_new= pd.DataFrame({'A': np.repeat(df.A,df.B.map(d).apply(len)).\
                  reset_index(drop=True),'B':functools.reduce(operator.iadd, df.B.map(d),[])})
print(df_new)

    A  B
0   1  x
1   1  y
2   1  z
3   2  x
4   2  w
5   2  r
6   3  x
7   3  q
8   4  x
9   4  w
10  4  r
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/54626462

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档