row reading and editing in Fortran 90 - fortran

I am new to Fortran, I am trying to write a program to read a .txt file in which i have 24480 rows and ~ 6000 columns.
In each row (as individuals) i have genotypes indicated as 1 and 2, which if, for example, in row one, i have had 204 genotypes, first half of this genotypes (=102) belongs to individual's sire and second half of genotypes belongs to individual's dam. In addition each row has not equal values. So, how can i define for Fortran to read this file row by row and divide each row to two and put beside each element (i) to the mean+i.
For example i show two rows of my file as brief:
row1: 112122121112122111112121111211122121111121
row2: 21112111112112222121112121211121221212121111121112 1212
And so on.
Any help would be appreciated in advance.

you need to read each line as a string, get its length with len_trim(), then read each half into integer arrays:
character*10000 line
read(unit,'(a)')line
len=len_trim(line)
read(line,'(10000i1)')a(:len/2),b(:len/2)

Related

How to collect data and headers for non blank cells in a row in Sheets

I cannot find a solution to my problem:
I have a sheet with ~290 rows and ~80 columns. The first row and column are fixed/header.
I would like to collect non-blank values and their header into column B.
I've tried to search for solutions, but I'm not as good at excel, so I cannot wrap my head around most of the advice that I've found.
In Google Sheets you could use an Array formula. I got this:
The formula I've used:
=ArrayFormula(CONCATENATE(IF(--(C2:G2<>"")*COLUMN($C$1:$G$1)<>0;$C$1:$G$1&" "&C2:G2;"")))
This is how it works:
(--(C2:G2<>"") will return an array of 0 and 1 if the cell is blank or not
COLUMN($C$1:$G$1) will return an array of column numbers of each cell
(C2:G2<>"")*COLUMN($C$1:$G$1) we multiply both arrays, so we will get an array of column numbers of non blank cells and 0 of blank cells
<>0;$C$1:$G$1&" "&C2:G2;"") We check if each number in the array obtained in step 3 is 0 or not. If it's 0, it returns a null value, if not, it returns the value of cell
CONCATENATE will concatenate all values from previous array (step 4) so we concatenate null values with real values of non blank cells.
Not sure if this will make the sheet load slower if you have too many records.
Hope this helps
Excel is not the same Google Sheets
=ARRAYFORMULA(TRIM(REGEXREPLACE(
TRANSPOSE(
QUERY(TRANSPOSE(IF(C2:F13<>"",C1:F1 & ", ","")),,99^99)
),
"((\s+)|(,\s*$))",
" "
)))
My sample
use:
=ARRAYFORMULA(REGEXREPLACE(TRIM(TRANSPOSE(QUERY(TRANSPOSE(
IF(C2:G<>"", C1:G1&" "&C2:G&",", )),,99^99))), ",$", ))

How to count the number of blank cells in one column based on the first blank row in another column

I have a spreadsheet set up with tv program titles in column B, the next 20 or so columns are tracking different information about that title. I need to count the number of blank cells in column R relating to the range in column B that contains titles (ie, up to the first blank row in column B.)
I can easily set up a formula to count the number of empty cells in a given range in column R, the problem is as I add more titles to the sheet I would have to keep updating the range in the formula [a simple =COUNTIF(R3:R1108, "")]. I've done a little googling of the problem but haven't quite found anything that fits the situation. I thought I would be able to get the following to work but I didn't fully understand what was going on with them and they weren't giving the expected results.
I've tried these formulas:
=ArrayFormula(sum(MIN("B3:B"&MIN(IF((R3:R)>"",ROW(B3:B)-1)))))
=ArrayFormula(sum(INDIRECT("B3:B"&MIN(IF((R3:R)>"",ROW(B3:B)-1)))))
And
=if(SUM(B3:B)="","",SUM(R3:R))
All of the above formulas give "0" as the result. Based on the COUNTIF formula I have set up it should be 840, which is a number I would expect. Currently, there are 1106 rows containing data and 840 is a reasonable number to expect in this situation.
Is this what you're looking for?
=COUNTBLANK(INDIRECT(CONCATENATE("R",3,":R",(3+COUNTA(B3:B)))))
This counts the number of non-blank rows in the B column (starting at B3), and uses that to determine the rows to perform COUNTBLANK in, in column R (starting at R3). CONCATENATE is a way to give it a range by adding strings together, and the INDIRECT allows for the range reference to be a string.
a proper way would be:
=ARRAYFORMULA(COUNTBLANK(INDIRECT(ADDRESS(3, 18, 4)&":"&
ADDRESS(MAX(IF(B3:B<>"", ROW(B3:B), )), 18, 4)))
or shorter:
=ARRAYFORMULA(COUNTBLANK(INDIRECT("R3:"&
ADDRESS(MAX(IF(B3:B<>"", ROW(B3:B), )), 18, 4))))
or shorter:
=ARRAYFORMULA(COUNTBLANK(INDIRECT("R3:R"&MAX(IF(B3:B<>"", ROW(B3:B), ))))

Arrayformula count how many cells in a row are less than cells in another row only if both are nonzero/nonblank

I found this formula, =arrayformula(sumproduct($C$24:$C$31<B$24:B$31)) but I need it to ignore if one or both cells are 0 or blank.
I've tried and, and countifs, but I can't seem to figure it out.
=arrayformula(sumproduct($C$24:$C$31<B$24:B$31))
I want a number 0-8 for counting how many cells in the particular row are less than the compared row, but (i.e. 0<25) needs to be ignored.
try it like this:
=ARRAYFORMULA(SUM(IF((C2:C < B2:B) * (C2:C<>0), 1, 0)))

Reformat a dataframe based on final empty columns in python

I am working on scraping a table that has major and minor column names. When I do this, the table comes in having read both the column names and column groups, so the column names are misaligned in the dataframe like so (simplified):
unnamed1 unnamed2 unnamed3 Year Passing Rushing Receiving
2015 NA 200 60 NA NA NA
2014 NA 180 70 NA NA NA
My challenge is in shifting the column names so that 'Year' aligns over '2015' and so forth. The problem is then that the number of columns to shift does not remain constant from table to table (this is only one of many). My code at the moment looks like the following:
table1=read_html('http://www.pro-football-reference.com/players/T/TyexWi00.htm')
df=table1[0]
to_shift=len(df.dropna(how='all', axis=1).columns) #Number of empty columns to shift by
df2=df.dropna(how='all',axis=1) #Drop the empty columns
df2.columns=df.columns[-to_shift:] #Shift all columns left by the number i've found
The problem is that for a player that has none of one stat (passing in this simple example), there are completely blank columns in the middle of the dataframe as well as at the right end, so that the code shifts too far. Is there a clean way of counting the columns from right to left until one is not completely empty?
Much thanks, and I hope my question is clear!
Is there a clean way of counting the columns from right to left until one is not completely empty?
from itertools import takewhile
len(df.columns) - len(list(takewhile(lambda col: df[col].isnull().all(), reversed(df.columns)))) - 1
Explanation:
takewhile returns all elements of a list (beginning at the front) until the given condition is False. When we call it on reversed(df.columns), we get all elements from the end. With df[col].isnull().all() we can check whether all entries of a column are null (a.k.a. nan). Consequently the above takewhile expression returns the suffix of columns which are completely 'empty'. By calculating total_length - bad_suffix_length - 1, we get the first index for which the condition is not satisfied.
Adding to the correct response from Michael Hoff (Thank you very much!), the code has been edited to
to_shift=len(df.columns) - len(list(takewhile(lambda col: df[col].isnull().all(), reversed(df.columns)))) #Index of origianl dataframe to keep
df2=df.drop(list(takewhile(lambda col: df[col].isnull().all(), reversed(df.columns))),axis=1) #Drop the empty right side columns
colnames=df.columns[-to_shift:]
df2.columns=colnames

Obtaining the element number related to a node of a fastener in Abaqus

I am trying to change the stiffness of a fastener depending on a pressure on it. I am approaching this problem by using field variables and extracting the forces in a fastener from .fil file.
The problem is that I need to relate the node number provided by UFIELD to element number of the fastener in .fil file. I know that the .fil file contains that information in record no. 1900 but when I set if statement for that record, it is never hit in my subroutine. Although, when I convert my .fil file to ASCII I can see that information there.
The records No. 1 and No. 495 are hit properly and I can obtain the element number and internal forces in it.
Moreover, I have tried using GETPARTINFO both on the node I have and on the element. But it returns number not related to the node of my fastener or the element itself.
Additionally, I could not obtain fastener CTF from the node itself or the material point as the fasteners do not have material points.
If I assume that the nodes and the fastener are in the same order and just match them, my code works nicely on just few element in a tiny model. But in a large model with lots of fasteners, everything gets mixed up.
Any Ideas how to solve this or maybe some remarks on why I cant access key 1900 from my subroutine or why GETPARTINFO does not return what is to be expected?
Ok, I figured this out. The key 1900 in .fil file is printed before the default reading position of command
call DBFILE(0,ARRAY,JRCD)
In order to obtain the required key the file read position must be reset
call DBFILE(2,ARRAY,JRCD)
But the problem is that keys 1900, 1901, 1933 etc. are generated for every element in the model regardless of your specified elset. Thus I wrote a little subroutine to generate an array of fasteners with their element number and corresponding node number.
subroutine obtain_relation(REL)
INCLUDE 'ABA_PARAM.INC'
DIMENSION ARRAY(513),JRRAY(NPRECD,513),REL(500,3)
character*8 CVALUE
EQUIVALENCE (ARRAY(1),JRRAY(1,1)), (ARRAY(4),CVALUE)
!Rewinding the file
CALL DBFILE(2,ARRAY,JRCD)
i = 1
DO K1=1,999999
!Start reading output file
CALL DBFILE(0,ARRAY,JRCD)
!If the end of the end of pre-step records go to 120
IF (KEY .EQ. 2000) GO TO 120
!If the end of all records is reached go to position 120
IF (JRCD .NE. 0) GO TO 120
!The key of the output table is at second possition (first is length of
!the array)
KEY=JRRAY(1,2)
! Record 1900 contains information about element conectivity
IF (KEY .EQ. 1900) THEN
IF(trim(CVALUE).eq."CONN3D2") then
Rel(i,1) = JRRAY (1,3) ! <- Element number
Rel(i,2) = JRRAY (1,5) ! <- First node number
i = i + 1
END IF
END IF
ENDDO
120 Continue
Return
end
Call this subroutine only once at the start of the analysis after calling POSFIL inside URDFIL and it will return a double precision 3 dimensional matrix with first column containing fastener element number, second column - first node of corresponding fastener and the last one empty. I used the last column to store the corresponding forces.
Hope this was helpful for somebody.