如何使用rpy2将R数据框转换回Pandas?

40

我使用下面的代码将pandas数据框转换为R:

import pandas as pd
import pandas.rpy.common as com
import rpy2.robjects as ro
from rpy2.robjects.packages import importr

rdf = com.convert_to_r_dataframe(df)

我如何将rdf转换回pandas.DataFrame

df = f(rdf)

4
pandas.rpy 已于 pandas 0.20 中被移除。 - Franck Dernoncourt
5个回答

32
自从rpy2发布2.4.0版本以来,将数据框在rpy2pandas之间转换已作为可选模块包含在内。使用它,无需显式转换,将会实时完成。
文档包含示例(也可作为Jupyter笔记本使用-链接位于页面顶部附近): https://rpy2.github.io/doc/latest/html/pandas.html#interoperability-with-pandas 注意:对于这个问题的原始回答推荐以下内容。
from rpy2.robjects import pandas2ri
pandas2ri.activate()

如果出于任何原因希望进行显式转换,可以使用以下函数:pandas2ri.py2ri()pandas2ri.ri2py()(它们曾经是pandas2ri.pandas2ri()pandas2ri.ri2pandas())。
注意:自rpy2 3.3.0版本发布以来,显式转换如下所示。
import rpy2.robjects as ro

dt = pd.DataFrame()
# To R DataFrame
r_dt = ro.conversion.py2rpy(dt)
# To pandas DataFrame
pd_dt = ro.conversion.rpy2py(r_dt)

更多细节请查看此链接


我是Python的新手。当我使用上述函数时,我的分类对象会丢失并变成整数。 - Shintu Joseph
有关改变行为的任何想法吗?@Igautier - Shintu Joseph
1
你在使用哪个版本?这个回答有一点旧了(4.5年),转换因子的方式已经发生了变化:https://bitbucket.org/rpy2/rpy2/commits/29e8a62de897 - lgautier
是的,Igautier,我把它们搞定了。谢谢你回复。 - Shintu Joseph
1
@Hiyam,链接指向的文档是几天前发布的。虽然不是太旧,但仍可以使用。 - lgautier
显示剩余2条评论

12

正如lgautier所建议的那样,可以使用pandas2ri来完成。

以下是将rpy数据框(rdf)转换为pandas数据帧(pd_df)的示例代码:

from rpy2.robjects import pandas2ri

pd_df = pandas2ri.ri2py_dataframe(rdf)

这个操作会用整数替换R数据框的索引(如果一开始不是整数)。有人知道如何保留原始索引吗? - A. Slowey

9
根据您的导入,看起来它是:
com.convert_robj(rdf)

例如,
In [480]: dfrm
Out[480]:
           A          B  C
0   0.454459  49.916767  1
1   0.943284  50.878174  1
2   0.974856  50.335679  2
3   0.776600  50.782104  1
4   0.553895  50.084505  1
5   0.514018  50.719019  2
6   0.915413  50.513962  0
7   0.771571  49.859855  2
8   0.068619  49.409657  0
9   0.728141  50.945174  2
10  0.388115  47.879653  1
11  0.960172  49.680258  0
12  0.015216  50.067968  0
13  0.495024  50.286287  1
14  0.565954  49.909771  1
15  0.992279  49.009696  1
16  0.179934  49.554256  0
17  0.521243  47.854791  0
18  0.551241  51.076262  1
19  0.713271  49.418503  0
20  0.801716  50.660304  1

In [481]: rdfrm = com.convert_to_r_dataframe(dfrm)

In [482]: rdfrm
Out[482]:
<DataFrame - Python:0x14905cf8 / R:0x1600ee98>
[FloatVector, FloatVector, IntVector]
  A: <class 'rpy2.robjects.vectors.FloatVector'>
  <FloatVector - Python:0xf9d0b00 / R:0x140e2620>
[0.454459, 0.943284, 0.974856, ..., 0.551241, 0.713271, 0.801716]
  B: <class 'rpy2.robjects.vectors.FloatVector'>
  <FloatVector - Python:0xf9d0878 / R:0x125aa240>
[49.916767, 50.878174, 50.335679, ..., 51.076262, 49.418503, 50.660304]
  C: <class 'rpy2.robjects.vectors.IntVector'>
  <IntVector - Python:0x11fceef0 / R:0x13f0d918>
[       1,        1,        2, ...,        1,        0,        1]

In [483]: com.convert_robj(rdfrm)
Out[483]:
           A          B  C
0   0.454459  49.916767  1
1   0.943284  50.878174  1
2   0.974856  50.335679  2
3   0.776600  50.782104  1
4   0.553895  50.084505  1
5   0.514018  50.719019  2
6   0.915413  50.513962  0
7   0.771571  49.859855  2
8   0.068619  49.409657  0
9   0.728141  50.945174  2
10  0.388115  47.879653  1
11  0.960172  49.680258  0
12  0.015216  50.067968  0
13  0.495024  50.286287  1
14  0.565954  49.909771  1
15  0.992279  49.009696  1
16  0.179934  49.554256  0
17  0.521243  47.854791  0
18  0.551241  51.076262  1
19  0.713271  49.418503  0
20  0.801716  50.660304  1

使用文档:

In [475]: com.convert_robj?
Type:       function
String Form:<function convert_robj at 0x13e85848>
File:       /mnt/epd/7.3-2_pandas0.12/lib/python2.7/site-packages/pandas/rpy/common.py
Definition: com.convert_robj(obj, use_pandas=True)
Docstring:
Convert rpy2 object to a pandas-friendly form

Parameters
----------
obj : rpy2 object

Returns
-------
Non-rpy data structure, mix of NumPy and pandas objects

6
使用pandas来读取一个名为r_df的rpy2数据框,这将避免弃用警告"FutureWarning: from_items is deprecated. Use DataFrame.from_dict(dict(items), ...) instead"。 r_df的类型是"rpy2.robjects.vectors.DataFrame"。 pd_df的类型是"pandas.core.frame.DataFrame"。
代码:pd_df = pd.DataFrame.from_dict({ key : np.asarray(r_df.rx2(key)) for key in r_df.names })

以上的解决方案已经过时,但是对于最新的3.2.0版本的rpy2来说,这个方法似乎非常有效。 - COOLBEANS
适用于旧版和新版,且运行良好。 - alex3465
这是唯一对我有效的方法。 - Alex Vorobiev

3

其他解决方案似乎已经过时,对我不再起作用。

根据文档,这是当前将数据从/转换为 pandas/R 对象的方法。

import rpy2.robjects as ro
from rpy2.robjects import pandas2ri

从pandas到R:

with ro.default_converter + pandas2ri.converter:
  r_from_pd_df = ro.conversion.get_conversion().py2rpy(pd_df)

r_from_pd_df

从 R 到 pandas:

with ro.default_converter + pandas2ri.converter:
  pd_from_r_df = ro.conversion.get_conversion().rpy2py(r_df)

pd_from_r_df

这个只在 rpy2 版本 >=3.5.7 中起作用。


1
最后一个例子在rpy2 3.5.9中会给出AttributeError: __enter__ - Alex Vorobiev

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接