如何从 Pandas 中的两列形成元组列
Posted
技术标签:
【中文标题】如何从 Pandas 中的两列形成元组列【英文标题】:How to form tuple column from two columns in Pandas 【发布时间】:2013-04-08 12:06:33 【问题描述】:我有一个 Pandas DataFrame,我想将 'lat' 和 'long' 列组合成一个元组。
<class 'pandas.core.frame.DataFrame'>
Int64Index: 205482 entries, 0 to 209018
Data columns:
Month 205482 non-null values
Reported by 205482 non-null values
Falls within 205482 non-null values
Easting 205482 non-null values
Northing 205482 non-null values
Location 205482 non-null values
Crime type 205482 non-null values
long 205482 non-null values
lat 205482 non-null values
dtypes: float64(4), object(5)
我尝试使用的代码是:
def merge_two_cols(series):
return (series['lat'], series['long'])
sample['lat_long'] = sample.apply(merge_two_cols, axis=1)
但是,这会返回以下错误:
---------------------------------------------------------------------------
AssertionError Traceback (most recent call last)
<ipython-input-261-e752e52a96e6> in <module>()
2 return (series['lat'], series['long'])
3
----> 4 sample['lat_long'] = sample.apply(merge_two_cols, axis=1)
5
...
AssertionError: Block shape incompatible with manager
我该如何解决这个问题?
【问题讨论】:
【参考方案1】:In [10]: df
Out[10]:
A B lat long
0 1.428987 0.614405 0.484370 -0.628298
1 -0.485747 0.275096 0.497116 1.047605
2 0.822527 0.340689 2.120676 -2.436831
3 0.384719 -0.042070 1.426703 -0.634355
4 -0.937442 2.520756 -1.662615 -1.377490
5 -0.154816 0.617671 -0.090484 -0.191906
6 -0.705177 -1.086138 -0.629708 1.332853
7 0.637496 -0.643773 -0.492668 -0.777344
8 1.109497 -0.610165 0.260325 2.533383
9 -1.224584 0.117668 1.304369 -0.152561
In [11]: df['lat_long'] = df[['lat', 'long']].apply(tuple, axis=1)
In [12]: df
Out[12]:
A B lat long lat_long
0 1.428987 0.614405 0.484370 -0.628298 (0.484370195967, -0.6282975278)
1 -0.485747 0.275096 0.497116 1.047605 (0.497115615839, 1.04760475074)
2 0.822527 0.340689 2.120676 -2.436831 (2.12067574274, -2.43683074367)
3 0.384719 -0.042070 1.426703 -0.634355 (1.42670326172, -0.63435462504)
4 -0.937442 2.520756 -1.662615 -1.377490 (-1.66261469102, -1.37749004179)
5 -0.154816 0.617671 -0.090484 -0.191906 (-0.0904840623396, -0.191905582481)
6 -0.705177 -1.086138 -0.629708 1.332853 (-0.629707821728, 1.33285348929)
7 0.637496 -0.643773 -0.492668 -0.777344 (-0.492667604075, -0.777344111021)
8 1.109497 -0.610165 0.260325 2.533383 (0.26032456699, 2.5333825651)
9 -1.224584 0.117668 1.304369 -0.152561 (1.30436900612, -0.152560909725)
【讨论】:
太棒了。谢谢你。显然需要了解 lambda 函数。 这对您的数据有效吗?如果是这样,你能分享你的熊猫版本和数据吗?我想知道为什么你的代码不起作用,它应该。 版本为0.10.1_20130131。请原谅我的无知,但是为您上传部分数据的最佳方式是什么? (仍然是一个相对新手)。 我未能在 0.10.1 上重现。最好的上传方式?您可以创建生成包含随机数据的帧的代码,它具有相同的问题并共享该代码,或者腌制上面的帧(示例)并通过免费的大文件传输服务传输它。如何腌制(两行,不带“,”):import pickle, with open('sample.pickle', 'w') as file: pickle.dump(sample, file) 我对此表示赞同,因为我需要压缩 10 列并且不想给出数据框名称 10 次。只想给列名。【参考方案2】:熟悉zip
。在处理列数据时它会派上用场。
df['new_col'] = list(zip(df.lat, df.long))
它比使用apply
或map
更简单、更快捷。像np.dstack
这样的东西比zip
快两倍,但不会给你元组。
【讨论】:
在python3中,你必须使用list
。这应该工作:df['new_col'] = list(zip(df.lat, df.long))
@paulwasit 啊是的,我爱恨关系与 python 3 的懒惰行为。谢谢。
这种方法list(zip(df.lat, df.long))
在 124 毫秒内比 df[['lat', 'long']].apply(tuple, axis=1)
在 14.2 秒内处理 900k 行要高效得多。比例大于100。
我正在尝试将其与更长的列列表一起使用df['new_col'] = list(zip(df[cols_to_keep]))
,但不断收到错误消息:Length of values does not match length of index
有什么建议吗?
@PeterHansen 的回答对我有所帮助,但认为首先解压列表可能缺少* - 即df['new_col'] = list(zip(*[df[c] for c in cols_to_keep])
【参考方案3】:
Pandas 有 itertuples
方法可以做到这一点:
list(df[['lat', 'long']].itertuples(index=False, name=None))
【讨论】:
【参考方案4】:我想添加df.values.tolist()
。 (只要你不介意得到一列列表而不是元组)
import pandas as pd
import numpy as np
size = int(1e+07)
df = pd.DataFrame('a': np.random.rand(size), 'b': np.random.rand(size))
%timeit df.values.tolist()
1.47 s ± 38.9 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
%timeit list(zip(df.a,df.b))
1.92 s ± 131 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
【讨论】:
当您拥有的不仅仅是这两列时:%timeit df[['a', 'b']].values.tolist()
。它仍然快得多。
创建它的速度更快,但是在该列上的任何操作都将以元组形式更快。例如,尝试在一列列表和一列元组上调用 .value_counts()
。【参考方案5】:
你应该尝试使用pd.to_records(index=False)
:
import pandas as pd
df = pd.DataFrame('language': ['en', 'ar', 'es'], 'greeting': ['Hi', 'اهلا', 'Hola'])
df
language greeting
0 en Hi
1 ar اهلا
2 es Hola
df['list_of_tuples'] = list(df[['language', 'greeting']].to_records(index=False))
df['list_of_tuples']
0 [en, Hi]
1 [ar, اهلا]
2 [es, Hola]
享受吧!
【讨论】:
以上是关于如何从 Pandas 中的两列形成元组列的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Python 中创建具有两列作为元组或 Pandas 数据框的单个变量?