免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
123下一页
最近访问板块 发新帖
查看: 13492 | 回复: 20
打印 上一主题 下一主题

python 如何按列合并两个文件? [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2016-04-29 02:34 |只看该作者 |倒序浏览
数据如下:
dat1='''
a        11
b        12
c        13
'''

dat2='''
d        1.3
a        2.4
b        4.3
v        2.2
c        3.4
'''
如何按第1列合并数据,得到以下结果:
a        11        2.4
b        12        4.3
c        13        3.4

求指导!!!
本来我的想法是,把数据都存成二维数组,然后循环dat1的第1列,判断dat2有没有,有的合在一块。
可是找了很久,卡在怎么取dat2的第1列,怎么能一下子取出某列呢?
网上看有人推荐Pandas 正在学习……

论坛徽章:
4
程序设计版块每日发帖之星
日期:2015-10-14 06:20:00每日论坛发贴之星
日期:2015-10-14 06:20:00程序设计版块每日发帖之星
日期:2016-05-02 06:20:00程序设计版块每日发帖之星
日期:2016-05-08 06:20:00
2 [报告]
发表于 2016-04-29 09:40 |只看该作者
本帖最后由 mswsg 于 2016-04-29 10:40 编辑

先占楼,你起得这么早呢
  1. python test.py --input1 dat1.txt --input2 dat2.txt > 2.out.txt
复制代码
  1. #!/usr/bin/env python
  2. # -*- coding: utf-8 -*-
  3. __author__ = 'shengwei ma'
  4. __author_email__ = 'shengweima@icloud.com'
  5. import sys
  6. import getopt

  7. input_file1 = ""
  8. input_file2 = ""

  9. try:
  10.    opts, args = getopt.getopt(sys.argv[1:], "h", ["input1=", "input2="])
  11. except getopt.GetoptError as err:
  12.     print(str(err))
  13. for op, value in opts:
  14.     if op == "--input1":
  15.         input_file1 = value
  16.     elif op == "--input2":
  17.         input_file2 = value
  18.     elif op == "-h":
  19.         print("python get_value_according_first_column.py --input1 dat1 --input2 dat2 > out.txt")
  20.         sys.exit()
  21. #  以上可忽略,定义shell中接受的参数及数据

  22. f1 = open(input_file1, 'r')
  23. f2 = open(input_file2, 'r')
  24. lines1 = f1.readlines()    # 将整个文件读作一个列表,可以添加 print lines1 查看,这里一行表示里边的一个元素(字符串),如lines1[0],则表示第一行
  25. lines2 = f2.readlines()    # 将整个文件读作一个列表,可以添加 print lines2 查看,第一行第一列,lines2[0][0]
  26. for line1 in lines1:       # 遍历列表lines1中的每个元素,及遍历读取文件1的每一行
  27.     line1 = line1.strip().split()  # 这里的一行就是一个字符串,使用字符串的strip方法,去掉行尾换行符,使用split分割字符串成列表
  28.     for line2 in lines2:
  29.         line2 = line2.strip().split()  # 同样 遍历文件2中每一行
  30.         if line1[0] in line2:    # line1[0] (注意是line 不是lines) 表示某一行的第一列,即查询某行第一列是否在文件2中,如果在
  31.             line1.extend(line2[1:])    # 在的话,则将 文件2中的第二列以后的部分添加到第一行的后边
  32.     print ' '.join(line1)   # 将列表 line1 转换成字符串打印
  33. f1.close()   # 关闭文件
  34. f2.close()   # 关闭文件
复制代码

论坛徽章:
0
3 [报告]
发表于 2016-04-29 11:09 |只看该作者
回复 2# mswsg


谢谢,前面的没看明白,后面的看明白了。感觉python代码好长啊,我以前学R的,用R的话一句话就搞定了。不过R没有python运算速度快,问下python的哲学是不是都得用循环?而没有什么高级函数,都要自己造轮子?

论坛徽章:
5
巨蟹座
日期:2014-08-28 18:12:342015年迎新春徽章
日期:2015-03-04 10:01:4415-16赛季CBA联赛之江苏
日期:2016-04-28 09:43:3115-16赛季CBA联赛之吉林
日期:2016-06-22 10:34:4315-16赛季CBA联赛之山西
日期:2016-08-16 16:29:55
4 [报告]
发表于 2016-04-29 11:25 |只看该作者
本帖最后由 Linux_manne 于 2016-04-29 11:34 编辑

感觉长 那就简化下
  1. f1 = open('1.txt', 'r').readlines()
  2. f2 = open('2.txt', 'r').readlines()

  3. print [ (l1.split()[0], l1.split()[1], l2.split()[1]) for l1 in f1 for l2 in f2 if l1.split()[0] == l2.split()[0] ]
复制代码
###########  不嵌套tuple 的############

  1. print [ "{0[0]} {0[1]} {1[1]}".format(l1.split(), l2.split()) for l1 in f1 for l2 in f2 if l1.split()[0] == l2.split()[0] ]
复制代码

论坛徽章:
5
巨蟹座
日期:2014-08-28 18:12:342015年迎新春徽章
日期:2015-03-04 10:01:4415-16赛季CBA联赛之江苏
日期:2016-04-28 09:43:3115-16赛季CBA联赛之吉林
日期:2016-06-22 10:34:4315-16赛季CBA联赛之山西
日期:2016-08-16 16:29:55
5 [报告]
发表于 2016-04-29 11:29 |只看该作者
回复 3# 小风0000


    python 有很多pythonic 的写法... 可惜 这个要很有经验的人才 写的出来, 上述那种简洁的写法 其实还可以优化..

论坛徽章:
4
程序设计版块每日发帖之星
日期:2015-10-14 06:20:00每日论坛发贴之星
日期:2015-10-14 06:20:00程序设计版块每日发帖之星
日期:2016-05-02 06:20:00程序设计版块每日发帖之星
日期:2016-05-08 06:20:00
6 [报告]
发表于 2016-04-29 11:29 |只看该作者
本帖最后由 mswsg 于 2016-04-29 11:34 编辑

这个列表解析,如果能理解,这个好。
是不是自己造轮子,我还真不知道,对于初学者应用基本python知识造轮子其实还挺好的。
有没有其他第三方模块,暂时未知回复 4# Linux_manne


   

论坛徽章:
5
巨蟹座
日期:2014-08-28 18:12:342015年迎新春徽章
日期:2015-03-04 10:01:4415-16赛季CBA联赛之江苏
日期:2016-04-28 09:43:3115-16赛季CBA联赛之吉林
日期:2016-06-22 10:34:4315-16赛季CBA联赛之山西
日期:2016-08-16 16:29:55
7 [报告]
发表于 2016-04-29 11:40 |只看该作者
回复 6# mswsg


    你应该回复lz  而不是我.......

论坛徽章:
0
8 [报告]
发表于 2016-04-29 11:51 |只看该作者
谢谢大家,还是不好高骛远了,先把基础打好,能得到结果才是硬道理!

论坛徽章:
3
程序设计版块每日发帖之星
日期:2016-02-23 06:20:0015-16赛季CBA联赛之八一
日期:2017-10-26 17:58:2515-16赛季CBA联赛之北控
日期:2017-11-02 10:50:56
9 [报告]
发表于 2016-04-29 11:57 |只看该作者
from os import linesep


f1 = open('/root/1.txt')
f2 = open('/root/2.txt')
f3 = open('/root/3.txt', 'w')
lines1 = f1.readlines()
lines2 = f2.readlines()

for line1 in lines1:
    k = line1.split()[0]
    for line2 in lines2:
        if line2.split()[0] == k:
            line3 = line1.replace(linesep, '') + "  " + str(line2.split()[1]) + linesep
            f3.write(line3)

f1.close()
f2.close()
f3.close()

论坛徽章:
0
10 [报告]
发表于 2016-04-29 12:11 |只看该作者
回复 1# 小风0000


这个最好用字典,而不用列表。速度会大不一样的。不信你用个大数据集>10000, 试试。

代码如下:
  1. with open("1.txt") as IN1, open("2.txt") as IN2:
  2.     f1 = { k:v for k,v in [l1.split() for l1 in IN1 ]}
  3.     f2 = { k:v for k, v in [l2.split() for l2 in IN2]}
  4.     print [ (k,f1[k],f2[k] ) for k in f2 if k in f1 ]
复制代码
  1. [('a', '2.4', '11'), ('c', '3.4', '13'), ('b', '4.3', '12')]
复制代码
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP