Python pandas - 提取多值属性

时间:2018-04-10 15:49:44

标签: python pandas scikit-learn data-cleaning multivalue

我刚开始使用Python,并希望使用Movielens数据集上的numpy / pandas包进行数据准备(尤其是包含MovieID,Movie Name和Year以及Genre的文件)。

屏幕截图:movielens - movie dataset

列类型是一个多值列,这对我来说是一个问题,因为我想尝试在数据集上使用机器学习算法。

目标:我希望获得有关电影属于哪种类型的是/否或0/1信息。

想法:检查'类型' column包含附加列的列名(单个流派名称)。如果是,请写入yes,否则立即在单元格中写入。这会迭代所有新列和所有行。

到目前为止完成:我将空/ NaN列附加到每个类型的数据帧。我也尝试使用dataframe.iloc['Genre'].str.contains(list(dataframe)[4]),如果名称匹配与否,它会给我结果为TRUE或FALSE。但是,如何以优雅的方式迭代和写入单元格呢?

非常感谢提前。 最好, 烫发

编辑:在这里你会发现到目前为止我所取得的成就。我使用管道分隔符拆分Genre列中的数据,重命名列并附加新列并删除旧列。如果我现在在所有列上使用get_dummies函数,则会创建例如根据Genre单元格单元格中显示的文本值,选择Genre1_Action' Genre1_Adventure',...,' Genre3Thriller' 我想要实现的是每个类型为每部电影获得单列。

# create a small test subset
subset1 = movie_data [0:9]
print("Original Dataset")
print(subset1)
# Split movie year and year in separate values -> append them to the df -> clean the Year column
tempY = subset1['MovieNameYear'].str.split('(').apply(pd.Series)
tempY.columns = ['MovieName','Year']
subset1 = pd.concat([subset1,tempY], axis=1, join='inner')
subset1['Year'] = subset1['Year'].str.replace(')','')
del subset1['MovieNameYear']

# split the column 'Genre' with the with the pipe separator in seperate columns
# name the columns of the temp value with the splitted values
# join the through split created columns to the existing subset and delete the original multi value column
tempG = subset1['Genre'].str.split('|').apply(pd.Series)
tempG.columns = ['Genre1','Genre2','Genre3']
subset1 = pd.concat([subset1, tempG], axis=1, join='inner')
del subset1['Genre']
print("Cleaned Dataset")
print(subset1)

dummiesTemp = pd.get_dummies(data=subset1, columns=['Genre1','Genre2','Genre3'])
print(dummiesTemp)

2 个答案:

答案 0 :(得分:1)

如果我理解你,你想要每个流派有一个列,表示T / F.我建议你看一下get_dummies函数

import pandas as pd
s = pd.Series(list('abca'))
pd.get_dummies(s)

更新 - 如果您有包含双值的列,则可以在之前或之后拆分它们。分裂之后的例子(猜测它最快,但应该测试)。代码可能更漂亮,但希望它清楚。

import pandas as pd
import numpy as np

s = pd.Series(['a', 'b', 'c', 'a|b', 'a|d'])
d = pd.get_dummies(s)

columns = list(d)
for col in columns:
    if '|' in col:
        for l in col.split('|'):
            if l in columns:
                d[l] = np.maximum(d[l].values, d[col].values)
            else:
                d[l] = d[col]

答案 1 :(得分:0)

这实际上应该是评论,但缺乏声誉:')。 Here我得到了一个不错的答案。

简而言之

private void Grid1_Loaded(object sender, RoutedEventArgs e)
{
            Grid1.CanUserAddRows = false;
}

这将为您提供一个包含 one-hot编码输出的数据框。

然后您可以通过:

将其加入原始的 df
private void TestButton_Click(object sender, RoutedEventArgs e)
{
    TestCollection.Add(new Test { Field1 = "Test", Field2 = "Test", Field3 = "Test", Field4 = "Test" });
    GridView.Refresh();

    foreach (var Column in Grid1.Columns.Where(b => b.Width.IsStar))
    {
        Column.Width = new DataGridLength(1, DataGridLengthUnitType.Auto);
        Grid1.UpdateLayout();
        Column.Width = new DataGridLength(1, DataGridLengthUnitType.Star);
        Grid1.UpdateLayout();
    }

}