【问题标题】:How to use Pandas to replace column entries in DataFrame and create dictionary new-old values如何使用 Pandas 替换 DataFrame 中的列条目并创建字典新旧值
【发布时间】:2019-01-07 13:28:52
【问题描述】:

我有一个文件,其中包含如下数据:

x y
z w
a b
a x
w y

我想创建一个包含以下替换字典的文件,该字典对每个字符串都有一个唯一的替换编号,该替换编号由从左到右和从上到下读取时字符串首次出现在文件中的顺序确定底部(注意这个应该被创建,它没有提供):

{'x':1, 'y':2, 'z':3, 'w':4 , 'a':5, 'b':6}

输出文件将是:

1 2
3 3
5 6
5 1
4 2

有没有什么有效的方法可以用 Pandas 创建已处理的文件和字典?

我想在以下策略中创建字典:

_counter = 0
def counter():
    global _counter
    _counter += 1
    return _counter
replacements_dict = collections.defaultdict(counter)

【问题讨论】:

  • 你是如何导出字典的?如果它是一个输入,那么您将无法获得比d = {'x':1, 'y':2, 'z':3, 'w':4, 'a':5, 'b':6} 更高效的方法。
  • Pandas 将如何创建字典?看起来您自己定义了替换。
  • 你的意思是字典是通过收集行,放在一起,丢弃重复的元素来创建的?
  • 您好,我添加了可以帮助创建字典的代码。是的,字典应该在航班上创建,而不是硬编码。
  • 我在结果字典中看不到任何模式。这些值看起来很随意。

标签: python pandas dictionary dataframe pandas-groupby


【解决方案1】:

您可以将factorizestack 创建的MultiIndex Series 一起使用,然后使用unstack,最后由to_csv 写入文件:

df = pd.read_csv(file, sep="\s+", header=None)

print (df)
   0  1
0  x  y
1  z  w
2  a  b
3  a  x
4  w  y

s = df.stack()
fact = pd.factorize(s)

#indexing is necessary
d = dict(zip(fact[1].values[fact[0]], fact[0] + 1))
print (d)
{'x': 1, 'y': 2, 'z': 3, 'w': 4, 'a': 5, 'b': 6}

对于新文件:

#values splited by ,
pd.Series(d).to_csv('dict.csv')
#read Series from file, convert to dict
d = pd.read_csv('dict.csv', index_col=[0], squeeze=True, header=None).to_dict()
print (d)
{'x': 1, 'y': 2, 'z': 3, 'w': 4, 'a': 5, 'b': 6}

df = pd.Series(fact[0] + 1, index=s.index).unstack()
print (df)

   0  1
0  1  2
1  3  4
2  5  6
3  5  1
4  4  2

df.to_csv('out', index=False, header=None)

【讨论】:

  • 感谢您的回答。我想在航班上创建字典,请参阅我编辑的问题
  • @Codevan - 所以需要用它们的计数替换值吗?如果是,请检查第二个答案。
  • @jezrael 我设法在问题下的最后评论中解决了这个问题。字典中的替换值是根据文件从左到右和从上到下读取时的字母顺序。 x是第一个遇到的字母,然后是y,然后是z,然后是w等等。
  • @roganjosh - 是的,在你发表评论之前真的不清楚。
  • @jezrael 但是现在我如何在另一个文件中获取或保存替换字典本身?
【解决方案2】:

我假设您希望字典 d 以这样一种方式分配给键的值对应于键的外观,在行中:

d={'col1':['x', 'y', 'a', 'a', 'w'], 'col2':['z','w','b','x','y']}
df=pd.DataFrame(d)

print(df)

输出:

  col1 col2
0    x    z
1    y    w
2    a    b
3    a    x
4    w    y

==================================

使用 itertools

import itertools
raw_list = list(itertools.chain(*[df.iloc[i].tolist() for i in range(df.shape[0])]))
d=dict()
counter=1
for k in raw_list:
    try: 
        _=d[k]
    except:
        d[k]=counter
        counter+=1

然后:

d

输出:

{'a': 5, 'b': 6, 'w': 4, 'x': 1, 'y': 3, 'z': 2}

希望对你有帮助!

============================================

使用因式分解

s = df.stack()
d=dict{}
for (x,y) in zip(pd.factorize(s)[1], pd.factorize(s)[0]+1):
    d[x]=y

【讨论】:

  • 谢谢!您认为使用上层人的答案进行分解没有办法做到这一点?
猜你喜欢
  • 2016-02-14
  • 1970-01-01
  • 2023-01-24
  • 2019-02-08
  • 2019-12-07
  • 2019-07-25
  • 2015-05-12
  • 1970-01-01
  • 2014-06-12
相关资源
最近更新 更多