Я знаю, что этот вопрос и ответ были пережеваны до смерти. Но я упомянул об этом для вдохновения для одной из проблем, которые у меня были. Я смог решить это, используя бит и куски из разных ответов, следовательно, предоставляя свой ответ, если кому-то это понадобится.
Мой метод является общим, в котором вы можете добавить дополнительные разделители посредством запятой, разделяющей переменную delimiters=
доказательство этого.
Рабочий код:
import pandas as pd
import re
df = pd.DataFrame({'$a':[1,2], '$b': [3,4],'$c':[5,6], '$d': [7,8], '$e': [9,10]})
delimiters = '$'
matchPattern = '|'.join(map(re.escape, delimiters))
df.columns = [re.split(matchPattern, i)[1] for i in df.columns ]
Выход:
>>> df
$a $b $c $d $e
0 1 3 5 7 9
1 2 4 6 8 10
>>> df
a b c d e
0 1 3 5 7 9
1 2 4 6 8 10
Вот ваш класс, с интерпретацией «колонки» его определения, а не с строкой; это будет важно для производительности; также дате ссылки
setClass("person", representation(name="character", age="numeric"))
pers <- new("person", name=c("John", "Tom"), age=c(20, 30))
date <- as.POSIXct(c('2013-01-01', '2013-01-02'))
Некоторые эксперименты, включая просмотр methods(class="POSIXct")
и обратное внимание к сообщениям об ошибках, привели меня к реализации as.data.frame.person
и format.person
(последний используется для отображения в данных .frame) как
as.data.frame.person <-
function(x, row.names=NULL, optional=FALSE, ...)
{
if (is.null(row.names))
row.names <- x@name
value <- list(x)
attr(value, "row.names") <- row.names
class(value) <- "data.frame"
value
}
format.person <- function(x, ...) paste0(x@name, ", ", x@age)
Это получает мои объекты в файле data.frame:
> lst <- list(id=1:2, date=date, pers=pers)
> as.data.frame(lst)
id date pers
John 1 2013-01-01 John, 20
Tom 2 2013-01-02 Tom, 30
Если я хочу подмножество, тогда мне нужно
setMethod("[", "person", function(x, i, j, ..., drop=TRUE) {
initialize(x, name=x@name[i], age=x@age[i])
})
Я не уверен, какие другие методы могут потребоваться по мере того, как встречаются больше операций data.frame
, нет «интерфейса data.frame».
Использование векторизованного класса в data.table кажется для использования метода длины для построения.
> library(data.table)
> data.table(id=1:2, pers=pers)
Error in data.table(id = 1:2, pers = pers) :
problem recycling column 2, try a simpler type
> setMethod(length, "person", function(x) length(x@name))
[1] "length"
> data.table(id=1:2, pers=pers)
id pers
1: 1 John, 20
2: 2 Tom, 30
Возможно, есть интерфейс data.table?
Судя по этой теме в списке рассылки:
http://tolstoy.newcastle.edu.au/R/e2/devel/06/11/1013.html
... Джон Чамберс думал об этом в 2006 году. И все же мы не можем помещать объекты S4 в столбцы кадров данных. Мы также не можем помещать сложные классы S3 в столбцы кадров данных.
Существуют и другие структуры табличных данных, которые могут это сделать - data.table возможно:
require(data.table)
setClass("geezer", representation(name="character", age="numeric"))
tom=new("geezer",name="Tom",age=20)
dick=new("geezer",name="Dick",age=23)
harry=new("geezer",name="Harry",age=25)
gt = data.table(geezers=c(tom,dick,harry),weapons=c("Gun","Gun","Knife"))
gt
geezers weapons
1: <geezer> Gun
2: <geezer> Gun
3: <geezer> Knife
Семантика data.table немного отличается от data.frame и не ожидает, что сможет подключить data.table к любому коду, использующему data.frame, и ожидать, что он будет работать (например, я подозреваю lm
и glm
пошатнутся). Но, кажется, авторы data.table допускают составные классы в столбцах ...