2016-05-27 89 views
0
city  state neighborhoods  categories 
Dravosburg PA  [asas,dfd]   ['Nightlife'] 
Dravosburg PA  [adad]    ['Auto_Repair','Automotive'] 

我有以上数据帧我想列表中的每个元素转换成列如:转换列表中的熊猫数据帧为列

city  state asas dfd adad Nightlife Auto_Repair Automotive 
Dravosburg PA 1  1 0 1   1   0  

我使用下面的代码来做到这一点:

def list2columns(df): 
""" 
to convert list in the columns 
of a dataframe 
""" 
columns=['categories','neighborhoods'] 
for col in columns:  
    for i in range(len(df)): 
     for element in eval(df.loc[i,"categories"]): 
      if len(element)!=0: 
       if element not in df.columns: 
        df.loc[:,element]=0 
       else: 
        df.loc[i,element]=1 
  1. 如何以更有效的方式做到这一点?
  2. 为什么仍然有如下的警告时,我使用df.loc已经

    SettingWithCopyWarning: A value is trying to be set on a copy of a slice 
    from a DataFrame.Try using .loc[row_indexer,col_indexer] = value instead 
    

回答

2

由于您使用eval(),我想每一列都有一个列表的字符串表示,而不是一个列表本身。此外,与上述示例不同,我假设您的neighborhoods列(df.iloc[0, 'neighborhoods'] == "['asas','dfd']")中的列表中的项目有引号,否则您的eval()会失败。

如果这是正确的,你可以尝试这样的事:

def list2columns(df): 
""" 
to convert list in the columns of a dataframe 
""" 
columns = ['categories','neighborhoods'] 
new_cols = set()  # list of all new columns added 
for col in columns:  
    for i in range(len(df[col])): 
     # get the list of columns to set 
     set_cols = eval(df.iloc[i, col]) 
     # set the values of these columns to 1 in the current row 
     # (if this causes new columns to be added, other rows will get nans) 
     df.iloc[i, set_cols] = 1 
     # remember which new columns have been added 
     new_cols.update(set_cols) 
# convert any un-set values in the new columns to 0 
df[list(new_cols)].fillna(value=0, inplace=True) 
# if that doesn't work, this may: 
# df.update(df[list(new_cols)].fillna(value=0)) 

我只能回答猜测你的第二个问题,关于SettingWithCopy警告。

这是可能(但不太可能),使用的df.iloc代替df.loc会有所帮助,因为这是意在通过行号(选择你的情况,df.loc[i, col]只有工作,因为你没有设置一个索引,所以熊猫使用默认索引,它与行号相匹配)。

另一种可能性是,传递到您的函数的df已经是来自较大数据框的切片,并且导致了SettingWithCopy警告。

我也发现使用df.loc与混合索引模式(列和行列名称的逻辑选择器)会产生SettingWithCopy警告;您的切片选择器可能会导致类似的问题。

希望在上面的代码中更简单,更直接的索引将解决任何这些问题。但如果您仍然看到该警告,请回报(并提供代码以生成df)。

2

使用这个代替

def list2columns(df): 
    """ 
    to convert list in the columns 
    of a dataframe 
    """ 
    df = df.copy() 
    columns=['categories','neighborhoods'] 
    for col in columns:  
     for i in range(len(df)): 
      for element in eval(df.loc[i,"categories"]): 
       if len(element)!=0: 
        if element not in df.columns: 
         df.loc[:,element]=0 
        else: 
         df.loc[i,element]=1 
    return df